PLT-2057 User as a first class object (#2648)

* Adding TeamMember to system

* Fixing all unit tests on the backend

* Fixing merge conflicts

* Fixing merge conflict

* Adding javascript unit tests

* Adding TeamMember to system

* Fixing all unit tests on the backend

* Fixing merge conflicts

* Fixing merge conflict

* Adding javascript unit tests

* Adding client side unit test

* Cleaning up the clint side tests

* Fixing msg

* Adding more client side unit tests

* Adding more using tests

* Adding last bit of client side unit tests and adding make cmd

* Fixing bad merge

* Fixing libraries

* Updating to new client side API

* Fixing borken unit test

* Fixing unit tests

* ugg...trying to beat gofmt

* ugg...trying to beat gofmt

* Cleaning up remainder of the server side routes

* Adding inital load api

* Increased coverage of webhook unit tests (#2660)

* Adding loading ... to root html

* Fixing bad merge

* Removing explicit content type so superagent will guess corectly (#2685)

* Fixing merge and unit tests

* Adding create team UI

* Fixing signup flows

* Adding LDAP unit tests and enterprise unit test helper (#2702)

* Add the ability to reset MFA from the commandline (#2706)

* Fixing compliance unit tests

* Fixing client side tests

* Adding open server to system console

* Moving websocket connection

* Fixing unit test

* Fixing unit tests

* Fixing unit tests

* Adding nickname and more LDAP unit tests (#2717)

* Adding join open teams

* Cleaning up all TODOs in the code

* Fixing web sockets

* Removing unused webockets file

* PLT-2533 Add the ability to reset a user's MFA from the system console (#2715)

* Add the ability to reset a user's MFA from the system console

* Add client side unit test for adminResetMfa

* Reorganizing authentication to fix LDAP error message (#2723)

* Fixing failing unit test

* Initial upgrade db code

* Adding upgrade script

* Fixing upgrade script after running on core

* Update OAuth and Claim routes to work with user model changes (#2739)

* Fixing perminant deletion. Adding ability to delete all user and the entire database (#2740)

* Fixing team invite ldap login call (#2741)

* Fixing bluebar and some img stuff

* Fix all the different file upload web utils (#2743)

* Fixing invalid session redirect (#2744)

* Redirect on bad channel name (#2746)

* Fixing a bunch of issue and removing dead code

* Patch to fix error message on leave channel (#2747)

* Setting EnableOpenServer to false by default

* Fixing config

* Fixing upgrade

* Fixing reported bugs

* Bug fixes for PLT-2057

* PLT-2563 Redo password recovery to use a database table (#2745)

* Redo password recovery to use a database table

* Update reset password audits

* Split out admin and user reset password APIs to be separate

* Delete password recovery when user is permanently deleted

* Consolidate password resetting into a single function

* Removed private channels as an option for outgoing webhooks (#2752)

* PLT-2577/PLT-2552 Fixes for backstage (#2753)

* Added URL to incoming webhook list

* Fixed client functions for adding/removing integrations

* Disallowed slash commands without trigger words

* Fixed clientside handling of errors on AddCommand page

* Minor auth cleanup (#2758)

* Changed EditPostModal to just close if you save without making any changes (#2759)

* Renamed client -> Client in async_client.jsx and fixed eslint warnings (#2756)

* Fixed url in channel info modal (#2755)

* Fixing reported issues

* Moving to version 3 of the apis

* Fixing command unit tests (#2760)

* Adding team admins

* Fixing DM issue

* Fixing eslint error

* Properly set EditPostModal's originalText state in all cases (#2762)

* Update client config check to assume features is defined if server is licensed (#2772)

* Fixing url link

* Fixing issue with websocket crashing when sending messages to different teams
Этот коммит содержится в:
Corey Hulen
2016-04-21 22:37:01 -07:00
родитель 5c755463ed
Коммит 2e5617c29b
268 изменённых файлов: 13214 добавлений и 9686 удалений

Просмотреть файл

@@ -22,21 +22,21 @@ import (
"time"
)
func InitPost(r *mux.Router) {
func InitPost() {
l4g.Debug(utils.T("api.post.init.debug"))
r.Handle("/posts/search", ApiUserRequired(searchPosts)).Methods("GET")
r.Handle("/posts/{post_id}", ApiUserRequired(getPostById)).Methods("GET")
BaseRoutes.NeedTeam.Handle("/posts/search", ApiUserRequired(searchPosts)).Methods("GET")
BaseRoutes.NeedTeam.Handle("/posts/{post_id}", ApiUserRequired(getPostById)).Methods("GET")
sr := r.PathPrefix("/channels/{id:[A-Za-z0-9]+}").Subrouter()
sr.Handle("/create", ApiUserRequired(createPost)).Methods("POST")
sr.Handle("/update", ApiUserRequired(updatePost)).Methods("POST")
sr.Handle("/posts/{offset:[0-9]+}/{limit:[0-9]+}", ApiUserRequiredActivity(getPosts, false)).Methods("GET")
sr.Handle("/posts/{time:[0-9]+}", ApiUserRequiredActivity(getPostsSince, false)).Methods("GET")
sr.Handle("/post/{post_id:[A-Za-z0-9]+}", ApiUserRequired(getPost)).Methods("GET")
sr.Handle("/post/{post_id:[A-Za-z0-9]+}/delete", ApiUserRequired(deletePost)).Methods("POST")
sr.Handle("/post/{post_id:[A-Za-z0-9]+}/before/{offset:[0-9]+}/{num_posts:[0-9]+}", ApiUserRequired(getPostsBefore)).Methods("GET")
sr.Handle("/post/{post_id:[A-Za-z0-9]+}/after/{offset:[0-9]+}/{num_posts:[0-9]+}", ApiUserRequired(getPostsAfter)).Methods("GET")
BaseRoutes.Posts.Handle("/create", ApiUserRequired(createPost)).Methods("POST")
BaseRoutes.Posts.Handle("/update", ApiUserRequired(updatePost)).Methods("POST")
BaseRoutes.Posts.Handle("/page/{offset:[0-9]+}/{limit:[0-9]+}", ApiUserRequiredActivity(getPosts, false)).Methods("GET")
BaseRoutes.Posts.Handle("/since/{time:[0-9]+}", ApiUserRequiredActivity(getPostsSince, false)).Methods("GET")
BaseRoutes.NeedPost.Handle("/get", ApiUserRequired(getPost)).Methods("GET")
BaseRoutes.NeedPost.Handle("/delete", ApiUserRequired(deletePost)).Methods("POST")
BaseRoutes.NeedPost.Handle("/before/{offset:[0-9]+}/{num_posts:[0-9]+}", ApiUserRequired(getPostsBefore)).Methods("GET")
BaseRoutes.NeedPost.Handle("/after/{offset:[0-9]+}/{num_posts:[0-9]+}", ApiUserRequired(getPostsAfter)).Methods("GET")
}
func createPost(c *Context, w http.ResponseWriter, r *http.Request) {
@@ -47,7 +47,7 @@ func createPost(c *Context, w http.ResponseWriter, r *http.Request) {
}
// Create and save post object to channel
cchan := Srv.Store.Channel().CheckPermissionsTo(c.Session.TeamId, post.ChannelId, c.Session.UserId)
cchan := Srv.Store.Channel().CheckPermissionsTo(c.TeamId, post.ChannelId, c.Session.UserId)
if !c.HasPermissionsToChannel(cchan, "createPost") {
return
@@ -228,15 +228,16 @@ func CreateWebhookPost(c *Context, channelId, text, overrideUsername, overrideIc
func handlePostEventsAndForget(c *Context, post *model.Post, triggerWebhooks bool) {
go func() {
tchan := Srv.Store.Team().Get(c.Session.TeamId)
tchan := Srv.Store.Team().Get(c.TeamId)
cchan := Srv.Store.Channel().Get(post.ChannelId)
uchan := Srv.Store.User().Get(post.UserId)
pchan := Srv.Store.User().GetProfiles(c.Session.TeamId)
pchan := Srv.Store.User().GetProfiles(c.TeamId)
dpchan := Srv.Store.User().GetDirectProfiles(c.Session.UserId)
mchan := Srv.Store.Channel().GetMembers(post.ChannelId)
var team *model.Team
if result := <-tchan; result.Err != nil {
l4g.Error(utils.T("api.post.handle_post_events_and_forget.team.error"), c.Session.TeamId, result.Err)
l4g.Error(utils.T("api.post.handle_post_events_and_forget.team.error"), c.TeamId, result.Err)
return
} else {
team = result.Data.(*model.Team)
@@ -252,12 +253,22 @@ func handlePostEventsAndForget(c *Context, post *model.Post, triggerWebhooks boo
var profiles map[string]*model.User
if result := <-pchan; result.Err != nil {
l4g.Error(utils.T("api.post.handle_post_events_and_forget.profiles.error"), c.Session.TeamId, result.Err)
l4g.Error(utils.T("api.post.handle_post_events_and_forget.profiles.error"), c.TeamId, result.Err)
return
} else {
profiles = result.Data.(map[string]*model.User)
}
if result := <-dpchan; result.Err != nil {
l4g.Error(utils.T("api.post.handle_post_events_and_forget.profiles.error"), c.TeamId, result.Err)
return
} else {
dps := result.Data.(map[string]*model.User)
for k, v := range dps {
profiles[k] = v
}
}
var members []model.ChannelMember
if result := <-mchan; result.Err != nil {
l4g.Error(utils.T("api.post.handle_post_events_and_forget.members.error"), post.ChannelId, result.Err)
@@ -282,7 +293,7 @@ func handlePostEventsAndForget(c *Context, post *model.Post, triggerWebhooks boo
}
if channel.Type == model.CHANNEL_DIRECT {
go makeDirectChannelVisible(c.Session.TeamId, post.ChannelId)
go makeDirectChannelVisible(c.TeamId, post.ChannelId)
}
}()
}
@@ -352,7 +363,7 @@ func handleWebhookEventsAndForget(c *Context, post *model.Post, team *model.Team
return
}
hchan := Srv.Store.Webhook().GetOutgoingByTeam(c.Session.TeamId)
hchan := Srv.Store.Webhook().GetOutgoingByTeam(c.TeamId)
hooks := []*model.OutgoingWebhook{}
@@ -416,8 +427,25 @@ func handleWebhookEventsAndForget(c *Context, post *model.Post, team *model.Team
respProps := model.MapFromJson(resp.Body)
// copy the context and create a mock session for posting the message
mockSession := model.Session{UserId: hook.CreatorId, TeamId: hook.TeamId, IsOAuth: false}
newContext := &Context{mockSession, model.NewId(), "", c.Path, nil, c.teamURLValid, c.teamURL, c.siteURL, c.T, c.Locale}
mockSession := model.Session{
UserId: hook.CreatorId,
TeamMembers: []*model.TeamMember{{TeamId: hook.TeamId, UserId: hook.CreatorId}},
IsOAuth: false,
}
newContext := &Context{
Session: mockSession,
RequestId: model.NewId(),
IpAddress: "",
Path: c.Path,
Err: nil,
teamURLValid: c.teamURLValid,
teamURL: c.teamURL,
siteURL: c.siteURL,
T: c.T,
Locale: c.Locale,
TeamId: hook.TeamId,
}
if text, ok := respProps["text"]; ok {
if _, err := CreateWebhookPost(newContext, post.ChannelId, text, respProps["username"], respProps["icon_url"], post.Props, post.Type); err != nil {
@@ -706,7 +734,7 @@ func sendNotifications(c *Context, post *model.Post, team *model.Team, channel *
TLSClientConfig: &tls.Config{InsecureSkipVerify: *utils.Cfg.ServiceSettings.EnableInsecureOutgoingConnections},
}
httpClient := &http.Client{Transport: tr}
request, _ := http.NewRequest("POST", *utils.Cfg.EmailSettings.PushNotificationServer+"/api/v1/send_push", strings.NewReader(msg.ToJson()))
request, _ := http.NewRequest("POST", *utils.Cfg.EmailSettings.PushNotificationServer+model.API_URL_SUFFIX_V1+"/send_push", strings.NewReader(msg.ToJson()))
l4g.Debug(utils.T("api.post.send_notifications_and_forget.push_notification.debug"), msg.DeviceId, msg.Message)
if _, err := httpClient.Do(request); err != nil {
@@ -719,7 +747,7 @@ func sendNotifications(c *Context, post *model.Post, team *model.Team, channel *
}
}
message := model.NewMessage(c.Session.TeamId, post.ChannelId, post.UserId, model.ACTION_POSTED)
message := model.NewMessage(c.TeamId, post.ChannelId, post.UserId, model.ACTION_POSTED)
message.Add("post", post.ToJson())
message.Add("channel_type", channel.Type)
@@ -780,7 +808,7 @@ func checkForOutOfChannelMentions(c *Context, post *model.Post, channel *model.C
}
SendEphemeralPost(
c.Session.TeamId,
c.TeamId,
post.UserId,
&model.Post{
ChannelId: post.ChannelId,
@@ -847,7 +875,7 @@ func updatePost(c *Context, w http.ResponseWriter, r *http.Request) {
return
}
cchan := Srv.Store.Channel().CheckPermissionsTo(c.Session.TeamId, post.ChannelId, c.Session.UserId)
cchan := Srv.Store.Channel().CheckPermissionsTo(c.TeamId, post.ChannelId, c.Session.UserId)
pchan := Srv.Store.Post().Get(post.Id)
if !c.HasPermissionsToChannel(cchan, "updatePost") {
@@ -889,7 +917,7 @@ func updatePost(c *Context, w http.ResponseWriter, r *http.Request) {
} else {
rpost := result.Data.(*model.Post)
message := model.NewMessage(c.Session.TeamId, rpost.ChannelId, c.Session.UserId, model.ACTION_POST_EDITED)
message := model.NewMessage(c.TeamId, rpost.ChannelId, c.Session.UserId, model.ACTION_POST_EDITED)
message.Add("post", rpost.ToJson())
PublishAndForget(message)
@@ -901,7 +929,7 @@ func updatePost(c *Context, w http.ResponseWriter, r *http.Request) {
func getPosts(c *Context, w http.ResponseWriter, r *http.Request) {
params := mux.Vars(r)
id := params["id"]
id := params["channel_id"]
if len(id) != 26 {
c.SetInvalidParam("getPosts", "channelId")
return
@@ -919,7 +947,7 @@ func getPosts(c *Context, w http.ResponseWriter, r *http.Request) {
return
}
cchan := Srv.Store.Channel().CheckPermissionsTo(c.Session.TeamId, id, c.Session.UserId)
cchan := Srv.Store.Channel().CheckPermissionsTo(c.TeamId, id, c.Session.UserId)
etagChan := Srv.Store.Post().GetEtag(id)
if !c.HasPermissionsToChannel(cchan, "getPosts") {
@@ -949,7 +977,7 @@ func getPosts(c *Context, w http.ResponseWriter, r *http.Request) {
func getPostsSince(c *Context, w http.ResponseWriter, r *http.Request) {
params := mux.Vars(r)
id := params["id"]
id := params["channel_id"]
if len(id) != 26 {
c.SetInvalidParam("getPostsSince", "channelId")
return
@@ -961,7 +989,7 @@ func getPostsSince(c *Context, w http.ResponseWriter, r *http.Request) {
return
}
cchan := Srv.Store.Channel().CheckPermissionsTo(c.Session.TeamId, id, c.Session.UserId)
cchan := Srv.Store.Channel().CheckPermissionsTo(c.TeamId, id, c.Session.UserId)
pchan := Srv.Store.Post().GetPostsSince(id, time)
if !c.HasPermissionsToChannel(cchan, "getPostsSince") {
@@ -982,7 +1010,7 @@ func getPostsSince(c *Context, w http.ResponseWriter, r *http.Request) {
func getPost(c *Context, w http.ResponseWriter, r *http.Request) {
params := mux.Vars(r)
channelId := params["id"]
channelId := params["channel_id"]
if len(channelId) != 26 {
c.SetInvalidParam("getPost", "channelId")
return
@@ -994,7 +1022,7 @@ func getPost(c *Context, w http.ResponseWriter, r *http.Request) {
return
}
cchan := Srv.Store.Channel().CheckPermissionsTo(c.Session.TeamId, channelId, c.Session.UserId)
cchan := Srv.Store.Channel().CheckPermissionsTo(c.TeamId, channelId, c.Session.UserId)
pchan := Srv.Store.Post().Get(postId)
if !c.HasPermissionsToChannel(cchan, "getPost") {
@@ -1041,7 +1069,7 @@ func getPostById(c *Context, w http.ResponseWriter, r *http.Request) {
}
post := list.Posts[list.Order[0]]
cchan := Srv.Store.Channel().CheckPermissionsTo(c.Session.TeamId, post.ChannelId, c.Session.UserId)
cchan := Srv.Store.Channel().CheckPermissionsTo(c.TeamId, post.ChannelId, c.Session.UserId)
if !c.HasPermissionsToChannel(cchan, "getPostById") {
return
}
@@ -1058,7 +1086,7 @@ func getPostById(c *Context, w http.ResponseWriter, r *http.Request) {
func deletePost(c *Context, w http.ResponseWriter, r *http.Request) {
params := mux.Vars(r)
channelId := params["id"]
channelId := params["channel_id"]
if len(channelId) != 26 {
c.SetInvalidParam("deletePost", "channelId")
return
@@ -1070,7 +1098,7 @@ func deletePost(c *Context, w http.ResponseWriter, r *http.Request) {
return
}
cchan := Srv.Store.Channel().CheckPermissionsTo(c.Session.TeamId, channelId, c.Session.UserId)
cchan := Srv.Store.Channel().CheckPermissionsTo(c.TeamId, channelId, c.Session.UserId)
pchan := Srv.Store.Post().Get(postId)
if result := <-pchan; result.Err != nil {
@@ -1106,11 +1134,11 @@ func deletePost(c *Context, w http.ResponseWriter, r *http.Request) {
return
}
message := model.NewMessage(c.Session.TeamId, post.ChannelId, c.Session.UserId, model.ACTION_POST_DELETED)
message := model.NewMessage(c.TeamId, post.ChannelId, c.Session.UserId, model.ACTION_POST_DELETED)
message.Add("post", post.ToJson())
PublishAndForget(message)
DeletePostFilesAndForget(c.Session.TeamId, post)
DeletePostFilesAndForget(c.TeamId, post)
result := make(map[string]string)
result["id"] = postId
@@ -1146,7 +1174,7 @@ func getPostsAfter(c *Context, w http.ResponseWriter, r *http.Request) {
func getPostsBeforeOrAfter(c *Context, w http.ResponseWriter, r *http.Request, before bool) {
params := mux.Vars(r)
id := params["id"]
id := params["channel_id"]
if len(id) != 26 {
c.SetInvalidParam("getPostsBeforeOrAfter", "channelId")
return
@@ -1170,7 +1198,7 @@ func getPostsBeforeOrAfter(c *Context, w http.ResponseWriter, r *http.Request, b
return
}
cchan := Srv.Store.Channel().CheckPermissionsTo(c.Session.TeamId, id, c.Session.UserId)
cchan := Srv.Store.Channel().CheckPermissionsTo(c.TeamId, id, c.Session.UserId)
// We can do better than this etag in this situation
etagChan := Srv.Store.Post().GetEtag(id)
@@ -1215,7 +1243,7 @@ func searchPosts(c *Context, w http.ResponseWriter, r *http.Request) {
for _, params := range paramsList {
// don't allow users to search for everything
if params.Terms != "*" {
channels = append(channels, Srv.Store.Post().Search(c.Session.TeamId, c.Session.UserId, params))
channels = append(channels, Srv.Store.Post().Search(c.TeamId, c.Session.UserId, params))
}
}