merging
Этот коммит содержится в:
@@ -17,7 +17,7 @@ import (
|
||||
)
|
||||
|
||||
func InitAdmin(r *mux.Router) {
|
||||
l4g.Debug("Initializing admin api routes")
|
||||
l4g.Debug(utils.T("api.admin.init.debug"))
|
||||
|
||||
sr := r.PathPrefix("/admin").Subrouter()
|
||||
sr.Handle("/logs", ApiUserRequired(getLogs)).Methods("GET")
|
||||
@@ -41,7 +41,7 @@ func getLogs(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
file, err := os.Open(utils.GetLogFileLocation(utils.Cfg.LogSettings.FileLocation))
|
||||
if err != nil {
|
||||
c.Err = model.NewAppError("getLogs", "Error reading log file", err.Error())
|
||||
c.Err = model.NewLocAppError("getLogs", "api.admin.file_read_error", nil, err.Error())
|
||||
}
|
||||
|
||||
defer file.Close()
|
||||
@@ -132,7 +132,7 @@ func testEmail(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
c.Err = result.Err
|
||||
return
|
||||
} else {
|
||||
if err := utils.SendMailUsingConfig(result.Data.(*model.User).Email, "Mattermost - Testing Email Settings", "<br/><br/><br/>It appears your Mattermost email is setup correctly!", cfg); err != nil {
|
||||
if err := utils.SendMailUsingConfig(result.Data.(*model.User).Email, c.T("api.admin.test_email.subject"), c.T("api.admin.test_email.body"), cfg); err != nil {
|
||||
c.Err = err
|
||||
return
|
||||
}
|
||||
|
||||
10
api/api.go
10
api/api.go
@@ -10,6 +10,9 @@ import (
|
||||
"github.com/mattermost/platform/utils"
|
||||
"html/template"
|
||||
"net/http"
|
||||
|
||||
_ "github.com/cloudfoundry/jibber_jabber"
|
||||
_ "github.com/nicksnyder/go-i18n/i18n"
|
||||
)
|
||||
|
||||
var ServerTemplates *template.Template
|
||||
@@ -21,13 +24,14 @@ func NewServerTemplatePage(templateName string) *ServerTemplatePage {
|
||||
TemplateName: templateName,
|
||||
Props: make(map[string]string),
|
||||
ClientCfg: utils.ClientCfg,
|
||||
Locale: model.DEFAULT_LOCALE,
|
||||
}
|
||||
}
|
||||
|
||||
func (me *ServerTemplatePage) Render() string {
|
||||
var text bytes.Buffer
|
||||
if err := ServerTemplates.ExecuteTemplate(&text, me.TemplateName, me); err != nil {
|
||||
l4g.Error("Error rendering template %v err=%v", me.TemplateName, err)
|
||||
l4g.Error(utils.T("api.api.render.error"), me.TemplateName, err)
|
||||
}
|
||||
|
||||
return text.String()
|
||||
@@ -49,10 +53,10 @@ func InitApi() {
|
||||
InitLicense(r)
|
||||
|
||||
templatesDir := utils.FindDir("api/templates")
|
||||
l4g.Debug("Parsing server templates at %v", templatesDir)
|
||||
l4g.Debug(utils.T("api.api.init.parsing_templates.debug"), templatesDir)
|
||||
var err error
|
||||
if ServerTemplates, err = template.ParseGlob(templatesDir + "*.html"); err != nil {
|
||||
l4g.Error("Failed to parse server templates %v", err)
|
||||
l4g.Error(utils.T("api.api.init.parsing_templates.error"), err)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -14,6 +14,7 @@ var Client *model.Client
|
||||
func Setup() {
|
||||
if Srv == nil {
|
||||
utils.LoadConfig("config.json")
|
||||
utils.InitTranslations()
|
||||
utils.Cfg.TeamSettings.MaxUsersPerTeam = 50
|
||||
NewServer()
|
||||
StartServer()
|
||||
|
||||
@@ -8,6 +8,7 @@ import (
|
||||
l4g "github.com/alecthomas/log4go"
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/mattermost/platform/model"
|
||||
"github.com/mattermost/platform/utils"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"strings"
|
||||
@@ -18,7 +19,7 @@ const (
|
||||
)
|
||||
|
||||
func InitChannel(r *mux.Router) {
|
||||
l4g.Debug("Initializing channel api routes")
|
||||
l4g.Debug(utils.T("api.channel.init.debug"))
|
||||
|
||||
sr := r.PathPrefix("/channels").Subrouter()
|
||||
sr.Handle("/", ApiUserRequiredActivity(getChannels, false)).Methods("GET")
|
||||
@@ -56,12 +57,12 @@ func createChannel(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
if channel.Type == model.CHANNEL_DIRECT {
|
||||
c.Err = model.NewAppError("createDirectChannel", "Must use createDirectChannel api service for direct message channel creation", "")
|
||||
c.Err = model.NewLocAppError("createDirectChannel", "api.channel.create_channel.direct_channel.app_error", nil, "")
|
||||
return
|
||||
}
|
||||
|
||||
if strings.Index(channel.Name, "__") > 0 {
|
||||
c.Err = model.NewAppError("createDirectChannel", "Invalid character '__' in channel name for non-direct channel", "")
|
||||
c.Err = model.NewLocAppError("createDirectChannel", "api.channel.create_channel.invalid_character.app_error", nil, "")
|
||||
return
|
||||
}
|
||||
|
||||
@@ -120,7 +121,7 @@ func createDirectChannel(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
func CreateDirectChannel(c *Context, otherUserId string) (*model.Channel, *model.AppError) {
|
||||
if len(otherUserId) != 26 {
|
||||
return nil, model.NewAppError("CreateDirectChannel", "Invalid other user id ", otherUserId)
|
||||
return nil, model.NewLocAppError("CreateDirectChannel", "api.channel.create_direct_channel.invalid_user.app_error", nil, otherUserId)
|
||||
}
|
||||
|
||||
uc := Srv.Store.User().Get(otherUserId)
|
||||
@@ -135,7 +136,7 @@ func CreateDirectChannel(c *Context, otherUserId string) (*model.Channel, *model
|
||||
channel.Type = model.CHANNEL_DIRECT
|
||||
|
||||
if uresult := <-uc; uresult.Err != nil {
|
||||
return nil, model.NewAppError("CreateDirectChannel", "Invalid other user id ", otherUserId)
|
||||
return nil, model.NewLocAppError("CreateDirectChannel", "api.channel.create_direct_channel.invalid_user.app_error", nil, otherUserId)
|
||||
}
|
||||
|
||||
cm1 := &model.ChannelMember{
|
||||
@@ -157,13 +158,13 @@ func CreateDirectChannel(c *Context, otherUserId string) (*model.Channel, *model
|
||||
}
|
||||
|
||||
func CreateDefaultChannels(c *Context, teamId string) ([]*model.Channel, *model.AppError) {
|
||||
townSquare := &model.Channel{DisplayName: "Town Square", Name: "town-square", Type: model.CHANNEL_OPEN, TeamId: teamId}
|
||||
townSquare := &model.Channel{DisplayName: c.T("api.channel.create_default_channels.town_square"), Name: "town-square", Type: model.CHANNEL_OPEN, TeamId: teamId}
|
||||
|
||||
if _, err := CreateChannel(c, townSquare, false); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
offTopic := &model.Channel{DisplayName: "Off-Topic", Name: "off-topic", Type: model.CHANNEL_OPEN, TeamId: teamId}
|
||||
offTopic := &model.Channel{DisplayName: c.T("api.channel.create_default_channels.off_topic"), Name: "off-topic", Type: model.CHANNEL_OPEN, TeamId: teamId}
|
||||
|
||||
if _, err := CreateChannel(c, offTopic, false); err != nil {
|
||||
return nil, err
|
||||
@@ -199,20 +200,20 @@ func updateChannel(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
if !strings.Contains(channelMember.Roles, model.CHANNEL_ROLE_ADMIN) && !strings.Contains(c.Session.Roles, model.ROLE_TEAM_ADMIN) {
|
||||
c.Err = model.NewAppError("updateChannel", "You do not have the appropriate permissions", "")
|
||||
c.Err = model.NewLocAppError("updateChannel", "api.channel.update_channel.permission.app_error", nil, "")
|
||||
c.Err.StatusCode = http.StatusForbidden
|
||||
return
|
||||
}
|
||||
|
||||
if oldChannel.DeleteAt > 0 {
|
||||
c.Err = model.NewAppError("updateChannel", "The channel has been archived or deleted", "")
|
||||
c.Err = model.NewLocAppError("updateChannel", "api.channel.update_channel.deleted.app_error", nil, "")
|
||||
c.Err.StatusCode = http.StatusBadRequest
|
||||
return
|
||||
}
|
||||
|
||||
if oldChannel.Name == model.DEFAULT_CHANNEL {
|
||||
if (len(channel.Name) > 0 && channel.Name != oldChannel.Name) || (len(channel.Type) > 0 && channel.Type != oldChannel.Type) {
|
||||
c.Err = model.NewAppError("updateChannel", "Tried to perform an invalid update of the default channel "+model.DEFAULT_CHANNEL, "")
|
||||
c.Err = model.NewLocAppError("updateChannel", "api.channel.update_channel.tried.app_error", map[string]interface{}{"Channel": model.DEFAULT_CHANNEL}, "")
|
||||
c.Err.StatusCode = http.StatusForbidden
|
||||
return
|
||||
}
|
||||
@@ -293,18 +294,18 @@ func PostUpdateChannelHeaderMessageAndForget(c *Context, channelId string, oldCh
|
||||
uc := Srv.Store.User().Get(c.Session.UserId)
|
||||
|
||||
if uresult := <-uc; uresult.Err != nil {
|
||||
l4g.Error("Failed to retrieve user while trying to save update channel header message %v", uresult.Err)
|
||||
l4g.Error(utils.T("api.channel.post_update_channel_header_message_and_forget.retrieve_user.error"), uresult.Err)
|
||||
return
|
||||
} else {
|
||||
user := uresult.Data.(*model.User)
|
||||
|
||||
var message string
|
||||
if oldChannelHeader == "" {
|
||||
message = fmt.Sprintf("%s updated the channel header to: %s", user.Username, newChannelHeader)
|
||||
message = fmt.Sprintf(c.T("api.channel.post_update_channel_header_message_and_forget.updated_to"), user.Username, newChannelHeader)
|
||||
} else if newChannelHeader == "" {
|
||||
message = fmt.Sprintf("%s removed the channel header (was: %s)", user.Username, oldChannelHeader)
|
||||
message = fmt.Sprintf(c.T("api.channel.post_update_channel_header_message_and_forget.removed"), user.Username, oldChannelHeader)
|
||||
} else {
|
||||
message = fmt.Sprintf("%s updated the channel header from: %s to: %s", user.Username, oldChannelHeader, newChannelHeader)
|
||||
message = fmt.Sprintf(c.T("api.channel.post_update_channel_header_message_and_forget.updated_from"), user.Username, oldChannelHeader, newChannelHeader)
|
||||
}
|
||||
|
||||
post := &model.Post{
|
||||
@@ -313,7 +314,7 @@ func PostUpdateChannelHeaderMessageAndForget(c *Context, channelId string, oldCh
|
||||
Type: model.POST_HEADER_CHANGE,
|
||||
}
|
||||
if _, err := CreatePost(c, post, false); err != nil {
|
||||
l4g.Error("Failed to post join/leave message %v", err)
|
||||
l4g.Error(utils.T("api.channel.post_update_channel_header_message_and_forget.join_leave.error"), err)
|
||||
}
|
||||
}
|
||||
}()
|
||||
@@ -367,12 +368,12 @@ func getChannels(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
// user is already in the team
|
||||
|
||||
if result := <-Srv.Store.Channel().GetChannels(c.Session.TeamId, c.Session.UserId); result.Err != nil {
|
||||
if result.Err.Message == "No channels were found" {
|
||||
if result.Err.Message == "No channels were found" { // store translation dependant
|
||||
// lets make sure the user is valid
|
||||
if result := <-Srv.Store.User().Get(c.Session.UserId); result.Err != nil {
|
||||
c.Err = result.Err
|
||||
c.RemoveSessionCookie(w, r)
|
||||
l4g.Error("Error in getting users profile for id=%v forcing logout", c.Session.UserId)
|
||||
l4g.Error(utils.T("api.channel.get_channels.error"), c.Session.UserId)
|
||||
return
|
||||
}
|
||||
}
|
||||
@@ -408,7 +409,7 @@ func getChannelCounts(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
// user is already in the team
|
||||
|
||||
if result := <-Srv.Store.Channel().GetChannelCounts(c.Session.TeamId, c.Session.UserId); result.Err != nil {
|
||||
c.Err = model.NewAppError("getChannelCounts", "Unable to get channel counts from the database", result.Err.Message)
|
||||
c.Err = model.NewLocAppError("getChannelCounts", "api.channel.get_channel_counts.app_error", nil, result.Err.Message)
|
||||
return
|
||||
} else if HandleEtag(result.Data.(*model.ChannelCounts).Etag(), w, r) {
|
||||
return
|
||||
@@ -459,9 +460,9 @@ func JoinChannel(c *Context, channelId string, role string) {
|
||||
c.Err = err
|
||||
return
|
||||
}
|
||||
PostUserAddRemoveMessageAndForget(c, channel.Id, fmt.Sprintf(`%v has joined the channel.`, user.Username))
|
||||
PostUserAddRemoveMessageAndForget(c, channel.Id, fmt.Sprintf(c.T("api.channel.join_channel.post_and_forget"), user.Username))
|
||||
} else {
|
||||
c.Err = model.NewAppError("join", "You do not have the appropriate permissions", "")
|
||||
c.Err = model.NewLocAppError("join", "api.channel.join_channel.permissions.app_error", nil, "")
|
||||
c.Err.StatusCode = http.StatusForbidden
|
||||
return
|
||||
}
|
||||
@@ -476,24 +477,24 @@ func PostUserAddRemoveMessageAndForget(c *Context, channelId string, message str
|
||||
Type: model.POST_JOIN_LEAVE,
|
||||
}
|
||||
if _, err := CreatePost(c, post, false); err != nil {
|
||||
l4g.Error("Failed to post join/leave message %v", err)
|
||||
l4g.Error(utils.T("api.channel.post_user_add_remove_message_and_forget.error"), err)
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
func AddUserToChannel(user *model.User, channel *model.Channel) (*model.ChannelMember, *model.AppError) {
|
||||
if channel.DeleteAt > 0 {
|
||||
return nil, model.NewAppError("AddUserToChannel", "The channel has been archived or deleted", "")
|
||||
return nil, model.NewLocAppError("AddUserToChannel", "api.channel.add_user_to_channel.deleted.app_error", nil, "")
|
||||
}
|
||||
|
||||
if channel.Type != model.CHANNEL_OPEN && channel.Type != model.CHANNEL_PRIVATE {
|
||||
return nil, model.NewAppError("AddUserToChannel", "Can not add user to this channel type", "")
|
||||
return nil, model.NewLocAppError("AddUserToChannel", "api.channel.add_user_to_channel.type.app_error", nil, "")
|
||||
}
|
||||
|
||||
newMember := &model.ChannelMember{ChannelId: channel.Id, UserId: user.Id, NotifyProps: model.GetDefaultChannelNotifyProps()}
|
||||
if cmresult := <-Srv.Store.Channel().SaveMember(newMember); cmresult.Err != nil {
|
||||
l4g.Error("Failed to add member user_id=%v channel_id=%v err=%v", user.Id, channel.Id, cmresult.Err)
|
||||
return nil, model.NewAppError("AddUserToChannel", "Failed to add user to channel", "")
|
||||
return nil, model.NewLocAppError("AddUserToChannel", "api.channel.add_user.to.channel.failed.app_error", nil, "")
|
||||
}
|
||||
|
||||
go func() {
|
||||
@@ -559,13 +560,13 @@ func leave(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
if channel.Type == model.CHANNEL_DIRECT {
|
||||
c.Err = model.NewAppError("leave", "Cannot leave a direct message channel", "")
|
||||
c.Err = model.NewLocAppError("leave", "api.channel.leave.direct.app_error", nil, "")
|
||||
c.Err.StatusCode = http.StatusForbidden
|
||||
return
|
||||
}
|
||||
|
||||
if channel.Name == model.DEFAULT_CHANNEL {
|
||||
c.Err = model.NewAppError("leave", "Cannot leave the default channel "+model.DEFAULT_CHANNEL, "")
|
||||
c.Err = model.NewLocAppError("leave", "api.channel.leave.default.app_error", map[string]interface{}{"Channel": model.DEFAULT_CHANNEL}, "")
|
||||
c.Err.StatusCode = http.StatusForbidden
|
||||
return
|
||||
}
|
||||
@@ -577,7 +578,7 @@ func leave(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
RemoveUserFromChannel(c.Session.UserId, c.Session.UserId, channel)
|
||||
|
||||
PostUserAddRemoveMessageAndForget(c, channel.Id, fmt.Sprintf(`%v has left the channel.`, user.Username))
|
||||
PostUserAddRemoveMessageAndForget(c, channel.Id, fmt.Sprintf(c.T("api.channel.leave.left"), user.Username))
|
||||
|
||||
result := make(map[string]string)
|
||||
result["id"] = channel.Id
|
||||
@@ -623,19 +624,19 @@ func deleteChannel(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
if !strings.Contains(channelMember.Roles, model.CHANNEL_ROLE_ADMIN) && !strings.Contains(c.Session.Roles, model.ROLE_TEAM_ADMIN) {
|
||||
c.Err = model.NewAppError("deleteChannel", "You do not have the appropriate permissions", "")
|
||||
c.Err = model.NewLocAppError("deleteChannel", "api.channel.delete_channel.permissions.app_error", nil, "")
|
||||
c.Err.StatusCode = http.StatusForbidden
|
||||
return
|
||||
}
|
||||
|
||||
if channel.DeleteAt > 0 {
|
||||
c.Err = model.NewAppError("deleteChannel", "The channel has been archived or deleted", "")
|
||||
c.Err = model.NewLocAppError("deleteChannel", "api.channel.delete_channel.deleted.app_error", nil, "")
|
||||
c.Err.StatusCode = http.StatusBadRequest
|
||||
return
|
||||
}
|
||||
|
||||
if channel.Name == model.DEFAULT_CHANNEL {
|
||||
c.Err = model.NewAppError("deleteChannel", "Cannot delete the default channel "+model.DEFAULT_CHANNEL, "")
|
||||
c.Err = model.NewLocAppError("deleteChannel", "api.channel.delete_channel.cannot.app_error", map[string]interface{}{"Channel": model.DEFAULT_CHANNEL}, "")
|
||||
c.Err.StatusCode = http.StatusForbidden
|
||||
return
|
||||
}
|
||||
@@ -644,7 +645,7 @@ func deleteChannel(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
for _, hook := range incomingHooks {
|
||||
go func() {
|
||||
if result := <-Srv.Store.Webhook().DeleteIncoming(hook.Id, now); result.Err != nil {
|
||||
l4g.Error("Encountered error deleting incoming webhook, id=" + hook.Id)
|
||||
l4g.Error(utils.T("api.channel.delete_channel.incoming_webhook.error"), hook.Id)
|
||||
}
|
||||
}()
|
||||
}
|
||||
@@ -652,7 +653,7 @@ func deleteChannel(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
for _, hook := range outgoingHooks {
|
||||
go func() {
|
||||
if result := <-Srv.Store.Webhook().DeleteOutgoing(hook.Id, now); result.Err != nil {
|
||||
l4g.Error("Encountered error deleting outgoing webhook, id=" + hook.Id)
|
||||
l4g.Error(utils.T("api.channel.delete_channel.outgoing_webhook.error"), hook.Id)
|
||||
}
|
||||
}()
|
||||
}
|
||||
@@ -665,11 +666,11 @@ func deleteChannel(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
c.LogAudit("name=" + channel.Name)
|
||||
|
||||
post := &model.Post{ChannelId: channel.Id, Message: fmt.Sprintf(
|
||||
`%v has archived the channel.`,
|
||||
c.T("api.channel.delete_channel.archived"),
|
||||
user.Username)}
|
||||
if _, err := CreatePost(c, post, false); err != nil {
|
||||
l4g.Error("Failed to post archive message %v", err)
|
||||
c.Err = model.NewAppError("deleteChannel", "Failed to send archive message", "")
|
||||
l4g.Error(utils.T("api.channel.delete_channel.failed_post.error"), err)
|
||||
c.Err = model.NewLocAppError("deleteChannel", "api.channel.delete_channel.failed_send.app_error", nil, "")
|
||||
return
|
||||
}
|
||||
|
||||
@@ -743,7 +744,7 @@ func getChannelExtraInfo(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
if memberLimitString, ok := params["member_limit"]; !ok {
|
||||
memberLimit = defaultExtraMemberLimit
|
||||
} else if memberLimitInt64, err := strconv.ParseInt(memberLimitString, 10, 0); err != nil {
|
||||
c.Err = model.NewAppError("getChannelExtraInfo", "Failed to parse member limit", err.Error())
|
||||
c.Err = model.NewLocAppError("getChannelExtraInfo", "api.channel.get_channel_extra_info.member_limit.app_error", nil, err.Error())
|
||||
return
|
||||
} else {
|
||||
memberLimit = int(memberLimitInt64)
|
||||
@@ -790,7 +791,7 @@ func getChannelExtraInfo(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
if channel.DeleteAt > 0 {
|
||||
c.Err = model.NewAppError("getChannelExtraInfo", "The channel has been archived or deleted", "")
|
||||
c.Err = model.NewLocAppError("getChannelExtraInfo", "api.channel.get_channel_extra_info.deleted.app_error", nil, "")
|
||||
c.Err.StatusCode = http.StatusBadRequest
|
||||
return
|
||||
}
|
||||
@@ -825,17 +826,17 @@ func addMember(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
if nresult := <-nuc; nresult.Err != nil {
|
||||
c.Err = model.NewAppError("addMember", "Failed to find user to be added", "")
|
||||
c.Err = model.NewLocAppError("addMember", "api.channel.add_member.find_user.app_error", nil, "")
|
||||
return
|
||||
} else if cresult := <-sc; cresult.Err != nil {
|
||||
c.Err = model.NewAppError("addMember", "Failed to find channel", "")
|
||||
c.Err = model.NewLocAppError("addMember", "api.channel.add_member.find_channel.app_error", nil, "")
|
||||
return
|
||||
} else {
|
||||
channel := cresult.Data.(*model.Channel)
|
||||
nUser := nresult.Data.(*model.User)
|
||||
|
||||
if oresult := <-ouc; oresult.Err != nil {
|
||||
c.Err = model.NewAppError("addMember", "Failed to find user doing the adding", "")
|
||||
c.Err = model.NewLocAppError("addMember", "api.channel.add_member.user_adding.app_error", nil, "")
|
||||
return
|
||||
} else {
|
||||
oUser := oresult.Data.(*model.User)
|
||||
@@ -848,7 +849,7 @@ func addMember(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
c.LogAudit("name=" + channel.Name + " user_id=" + userId)
|
||||
|
||||
PostUserAddRemoveMessageAndForget(c, channel.Id, fmt.Sprintf(`%v added to the channel by %v`, nUser.Username, oUser.Username))
|
||||
PostUserAddRemoveMessageAndForget(c, channel.Id, fmt.Sprintf(c.T("api.channel.add_member.added"), nUser.Username, oUser.Username))
|
||||
|
||||
<-Srv.Store.Channel().UpdateLastViewedAt(id, oUser.Id)
|
||||
w.Write([]byte(cm.ToJson()))
|
||||
@@ -886,13 +887,13 @@ func removeMember(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
if !strings.Contains(removerChannelMember.Roles, model.CHANNEL_ROLE_ADMIN) && !c.IsTeamAdmin() {
|
||||
c.Err = model.NewAppError("updateChannel", "You do not have the appropriate permissions ", "")
|
||||
c.Err = model.NewLocAppError("updateChannel", "api.channel.remove_member.permissions.app_error", nil, "")
|
||||
c.Err.StatusCode = http.StatusForbidden
|
||||
return
|
||||
}
|
||||
|
||||
if err := RemoveUserFromChannel(userIdToRemove, c.Session.UserId, channel); err != nil {
|
||||
c.Err = model.NewAppError("updateChannel", "Unable to remove user.", err.Message)
|
||||
c.Err = model.NewLocAppError("updateChannel", "api.channel.remove_member.unable.app_error", nil, err.Message)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -908,7 +909,7 @@ func removeMember(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
func RemoveUserFromChannel(userIdToRemove string, removerUserId string, channel *model.Channel) *model.AppError {
|
||||
if channel.DeleteAt > 0 {
|
||||
return model.NewAppError("updateChannel", "The channel has been archived or deleted", "")
|
||||
return model.NewLocAppError("updateChannel", "api.channel.remove_user_from_channel.deleted.app_error", nil, "")
|
||||
}
|
||||
|
||||
if cmresult := <-Srv.Store.Channel().RemoveMember(channel.Id, userIdToRemove); cmresult.Err != nil {
|
||||
|
||||
@@ -15,6 +15,7 @@ import (
|
||||
"github.com/mattermost/platform/model"
|
||||
"github.com/mattermost/platform/store"
|
||||
"github.com/mattermost/platform/utils"
|
||||
goi18n "github.com/nicksnyder/go-i18n/i18n"
|
||||
)
|
||||
|
||||
var sessionCache *utils.Cache = utils.NewLru(model.SESSION_CACHE_SIZE)
|
||||
@@ -29,6 +30,8 @@ type Context struct {
|
||||
teamURL string
|
||||
siteURL string
|
||||
SessionTokenIndex int64
|
||||
T goi18n.TranslateFunc
|
||||
Locale string
|
||||
}
|
||||
|
||||
type Page struct {
|
||||
@@ -41,6 +44,7 @@ type Page struct {
|
||||
Channel *model.Channel
|
||||
PostID string
|
||||
SessionTokenIndex int64
|
||||
Locale string
|
||||
}
|
||||
|
||||
func ApiAppHandler(h func(*Context, http.ResponseWriter, *http.Request)) http.Handler {
|
||||
@@ -81,10 +85,10 @@ type handler struct {
|
||||
}
|
||||
|
||||
func (h handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
l4g.Debug("%v", r.URL.Path)
|
||||
|
||||
c := &Context{}
|
||||
c.T, c.Locale = utils.GetTranslationsAndLocale(w, r)
|
||||
c.RequestId = model.NewId()
|
||||
c.IpAddress = GetIpAddress(r)
|
||||
|
||||
@@ -164,10 +168,10 @@ func (h handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
if session == nil || session.IsExpired() {
|
||||
c.RemoveSessionCookie(w, r)
|
||||
c.Err = model.NewAppError("ServeHTTP", "Invalid or expired session, please login again.", "token="+token)
|
||||
c.Err = model.NewLocAppError("ServeHTTP", "api.context.session_expired.app_error", nil, "token="+token)
|
||||
c.Err.StatusCode = http.StatusUnauthorized
|
||||
} else if !session.IsOAuth && isTokenFromQueryString {
|
||||
c.Err = model.NewAppError("ServeHTTP", "Session is not OAuth but token was provided in the query string", "token="+token)
|
||||
c.Err = model.NewLocAppError("ServeHTTP", "api.context.token_provided.app_error", nil, "token="+token)
|
||||
c.Err.StatusCode = http.StatusUnauthorized
|
||||
} else {
|
||||
c.Session = *session
|
||||
@@ -194,7 +198,7 @@ func (h handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
if c.Err == nil && h.isUserActivity && token != "" && len(c.Session.UserId) > 0 {
|
||||
go func() {
|
||||
if err := (<-Srv.Store.User().UpdateUserAndSessionActivity(c.Session.UserId, c.Session.Id, model.GetMillis())).Err; err != nil {
|
||||
l4g.Error("Failed to update LastActivityAt for user_id=%v and session_id=%v, err=%v", c.Session.UserId, c.Session.Id, err)
|
||||
l4g.Error(utils.T("api.context.last_activity_at.error"), c.Session.UserId, c.Session.Id, err)
|
||||
}
|
||||
}()
|
||||
}
|
||||
@@ -204,6 +208,7 @@ func (h handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
if c.Err != nil {
|
||||
c.Err.Translate(c.T)
|
||||
c.Err.RequestId = c.RequestId
|
||||
c.LogError(c.Err)
|
||||
c.Err.Where = r.URL.Path
|
||||
@@ -249,13 +254,13 @@ func (c *Context) LogAuditWithUserId(userId, extraInfo string) {
|
||||
}
|
||||
|
||||
func (c *Context) LogError(err *model.AppError) {
|
||||
l4g.Error("%v:%v code=%v rid=%v uid=%v ip=%v %v [details: %v]", c.Path, err.Where, err.StatusCode,
|
||||
l4g.Error(utils.T("api.context.log.error"), c.Path, err.Where, err.StatusCode,
|
||||
c.RequestId, c.Session.UserId, c.IpAddress, err.Message, err.DetailedError)
|
||||
}
|
||||
|
||||
func (c *Context) UserRequired() {
|
||||
if len(c.Session.UserId) == 0 {
|
||||
c.Err = model.NewAppError("", "Invalid or expired session, please login again.", "UserRequired")
|
||||
c.Err = model.NewLocAppError("", "api.context.session_expired.app_error", nil, "UserRequired")
|
||||
c.Err.StatusCode = http.StatusUnauthorized
|
||||
return
|
||||
}
|
||||
@@ -263,11 +268,11 @@ func (c *Context) UserRequired() {
|
||||
|
||||
func (c *Context) SystemAdminRequired() {
|
||||
if len(c.Session.UserId) == 0 {
|
||||
c.Err = model.NewAppError("", "Invalid or expired session, please login again.", "SystemAdminRequired")
|
||||
c.Err = model.NewLocAppError("", "api.context.session_expired.app_error", nil, "SystemAdminRequired")
|
||||
c.Err.StatusCode = http.StatusUnauthorized
|
||||
return
|
||||
} else if !c.IsSystemAdmin() {
|
||||
c.Err = model.NewAppError("", "You do not have the appropriate permissions", "AdminRequired")
|
||||
c.Err = model.NewLocAppError("", "api.context.permissions.app_error", nil, "AdminRequired")
|
||||
c.Err.StatusCode = http.StatusForbidden
|
||||
return
|
||||
}
|
||||
@@ -285,7 +290,7 @@ func (c *Context) HasPermissionsToUser(userId string, where string) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
c.Err = model.NewAppError(where, "You do not have the appropriate permissions", "userId="+userId)
|
||||
c.Err = model.NewLocAppError(where, "api.context.permissions.app_error", nil, "userId="+userId)
|
||||
c.Err.StatusCode = http.StatusForbidden
|
||||
return false
|
||||
}
|
||||
@@ -300,7 +305,7 @@ func (c *Context) HasPermissionsToTeam(teamId string, where string) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
c.Err = model.NewAppError(where, "You do not have the appropriate permissions", "userId="+c.Session.UserId+", teamId="+teamId)
|
||||
c.Err = model.NewLocAppError(where, "api.context.permissions.app_error", nil, "userId="+c.Session.UserId+", teamId="+teamId)
|
||||
c.Err.StatusCode = http.StatusForbidden
|
||||
return false
|
||||
}
|
||||
@@ -310,7 +315,7 @@ func (c *Context) HasPermissionsToChannel(sc store.StoreChannel, where string) b
|
||||
c.Err = cresult.Err
|
||||
return false
|
||||
} else if cresult.Data.(int64) != 1 {
|
||||
c.Err = model.NewAppError(where, "You do not have the appropriate permissions", "userId="+c.Session.UserId)
|
||||
c.Err = model.NewLocAppError(where, "api.context.permissions.app_error", nil, "userId="+c.Session.UserId)
|
||||
c.Err.StatusCode = http.StatusForbidden
|
||||
return false
|
||||
}
|
||||
@@ -323,7 +328,7 @@ func (c *Context) HasSystemAdminPermissions(where string) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
c.Err = model.NewAppError(where, "You do not have the appropriate permissions (system)", "userId="+c.Session.UserId)
|
||||
c.Err = model.NewLocAppError(where, "api.context.system_permissions.app_error", nil, "userId="+c.Session.UserId)
|
||||
c.Err.StatusCode = http.StatusForbidden
|
||||
return false
|
||||
}
|
||||
@@ -371,12 +376,12 @@ func (c *Context) RemoveSessionCookie(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
func (c *Context) SetInvalidParam(where string, name string) {
|
||||
c.Err = model.NewAppError(where, "Invalid "+name+" parameter", "")
|
||||
c.Err = model.NewLocAppError(where, "api.context.invalid_param.app_error", map[string]interface{}{"Name": name}, "")
|
||||
c.Err.StatusCode = http.StatusBadRequest
|
||||
}
|
||||
|
||||
func (c *Context) SetUnknownError(where string, details string) {
|
||||
c.Err = model.NewAppError(where, "An unknown error has occured. Please contact support.", details)
|
||||
c.Err = model.NewLocAppError(where, "api.context.unknown.app_error", nil, details)
|
||||
}
|
||||
|
||||
func (c *Context) setTeamURL(url string, valid bool) {
|
||||
@@ -402,7 +407,7 @@ func (c *Context) GetTeamURL() string {
|
||||
if !c.teamURLValid {
|
||||
c.SetTeamURLFromSession()
|
||||
if !c.teamURLValid {
|
||||
l4g.Debug("TeamURL accessed when not valid. Team URL should not be used in api functions or those that are team independent")
|
||||
l4g.Debug(utils.T("api.context.invalid_team_url.debug"))
|
||||
}
|
||||
}
|
||||
return c.teamURL
|
||||
@@ -507,7 +512,7 @@ func RenderWebError(err *model.AppError, w http.ResponseWriter, r *http.Request)
|
||||
}
|
||||
|
||||
func Handle404(w http.ResponseWriter, r *http.Request) {
|
||||
err := model.NewAppError("Handle404", "Sorry, we could not find the page.", "")
|
||||
err := model.NewLocAppError("Handle404", "api.context.404.app_error", nil, "")
|
||||
err.StatusCode = http.StatusNotFound
|
||||
l4g.Error("%v: code=404 ip=%v", r.URL.Path, GetIpAddress(r))
|
||||
RenderWebError(err, w, r)
|
||||
@@ -521,7 +526,7 @@ func GetSession(token string) *model.Session {
|
||||
|
||||
if session == nil {
|
||||
if sessionResult := <-Srv.Store.Session().Get(token); sessionResult.Err != nil {
|
||||
l4g.Error("Invalid session token=" + token + ", err=" + sessionResult.Err.DetailedError)
|
||||
l4g.Error(utils.T("api.context.invalid_token.error"), token, sessionResult.Err.DetailedError)
|
||||
} else {
|
||||
session = sessionResult.Data.(*model.Session)
|
||||
|
||||
|
||||
@@ -70,10 +70,10 @@ func ExportToWriter(w io.Writer, options *ExportOptions) *model.AppError {
|
||||
|
||||
// Write our options to file
|
||||
if optionsFile, err := zipWriter.Create(EXPORT_OPTIONS_FILE); err != nil {
|
||||
return model.NewAppError("ExportToWriter", "Unable to create options file", err.Error())
|
||||
return model.NewLocAppError("ExportToWriter", "api.export.options.create.app_error", nil, err.Error())
|
||||
} else {
|
||||
if _, err := optionsFile.Write([]byte(options.ToJson())); err != nil {
|
||||
return model.NewAppError("ExportToWriter", "Unable to write to options file", err.Error())
|
||||
return model.NewLocAppError("ExportToWriter", "api.export.options.write.app_error", nil, err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -109,10 +109,10 @@ func ExportTeams(writer ExportWriter, options *ExportOptions) *model.AppError {
|
||||
teams[i].PreExport()
|
||||
|
||||
if teamFile, err := writer.Create(EXPORT_TEAMS_FOLDER + "/" + teams[i].Name + ".json"); err != nil {
|
||||
return model.NewAppError("ExportTeams", "Unable to open file for export", err.Error())
|
||||
return model.NewLocAppError("ExportTeams", "api.export.open_file.app_error", nil, err.Error())
|
||||
} else {
|
||||
if _, err := teamFile.Write([]byte(teams[i].ToJson())); err != nil {
|
||||
return model.NewAppError("ExportTeams", "Unable to write to team export file", err.Error())
|
||||
return model.NewLocAppError("ExportTeams", "api.export.write_file.app_error", nil, err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -162,10 +162,10 @@ func ExportChannels(writer ExportWriter, options *ExportOptions, teamId string)
|
||||
channels[i].PreExport()
|
||||
|
||||
if channelFile, err := writer.Create(EXPORT_CHANNELS_FOLDER + "/" + channels[i].Id + ".json"); err != nil {
|
||||
return model.NewAppError("ExportChannels", "Unable to open file for export", err.Error())
|
||||
return model.NewLocAppError("ExportChannels", "api.export.open_file.app_error", nil, err.Error())
|
||||
} else {
|
||||
if _, err := channelFile.Write([]byte(channels[i].ToJson())); err != nil {
|
||||
return model.NewAppError("ExportChannels", "Unable to write to export file", err.Error())
|
||||
return model.NewLocAppError("ExportChannels", "api.export.write_file.app_error", nil, err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -177,14 +177,14 @@ func ExportChannels(writer ExportWriter, options *ExportOptions, teamId string)
|
||||
}
|
||||
|
||||
if membersFile, err := writer.Create(EXPORT_CHANNELS_FOLDER + "/" + channels[i].Id + "_members.json"); err != nil {
|
||||
return model.NewAppError("ExportChannels", "Unable to open file for export", err.Error())
|
||||
return model.NewLocAppError("ExportChannels", "api.export.open_file.app_error", nil, err.Error())
|
||||
} else {
|
||||
result, err2 := json.Marshal(members)
|
||||
if err2 != nil {
|
||||
return model.NewAppError("ExportChannels", "Unable to convert to json", err.Error())
|
||||
return model.NewLocAppError("ExportChannels", "api.export.json.app_error", nil, err.Error())
|
||||
}
|
||||
if _, err3 := membersFile.Write([]byte(result)); err3 != nil {
|
||||
return model.NewAppError("ExportChannels", "Unable to write to export file", err.Error())
|
||||
return model.NewLocAppError("ExportChannels", "api.export.write_file.app_error", nil, err.Error())
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -209,14 +209,14 @@ func ExportPosts(writer ExportWriter, options *ExportOptions, channelId string)
|
||||
|
||||
// Export the posts
|
||||
if postsFile, err := writer.Create(EXPORT_POSTS_FOLDER + "/" + channelId + "_posts.json"); err != nil {
|
||||
return model.NewAppError("ExportPosts", "Unable to open file for export", err.Error())
|
||||
return model.NewLocAppError("ExportPosts", "api.export.open_file.app_error", nil, err.Error())
|
||||
} else {
|
||||
result, err2 := json.Marshal(posts)
|
||||
if err2 != nil {
|
||||
return model.NewAppError("ExportPosts", "Unable to convert to json", err.Error())
|
||||
return model.NewLocAppError("ExportPosts", "api.export.json.app_error", nil, err.Error())
|
||||
}
|
||||
if _, err3 := postsFile.Write([]byte(result)); err3 != nil {
|
||||
return model.NewAppError("ExportPosts", "Unable to write to export file", err.Error())
|
||||
return model.NewLocAppError("ExportPosts", "api.export.write_file.app_error", nil, err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -234,14 +234,14 @@ func ExportUsers(writer ExportWriter, options *ExportOptions, teamId string) *mo
|
||||
|
||||
// Write the users
|
||||
if usersFile, err := writer.Create(EXPORT_USERS_FOLDER + "/" + teamId + "_users.json"); err != nil {
|
||||
return model.NewAppError("ExportUsers", "Unable to open file for export", err.Error())
|
||||
return model.NewLocAppError("ExportUsers", "api.export.open_file.app_error", nil, err.Error())
|
||||
} else {
|
||||
result, err2 := json.Marshal(users)
|
||||
if err2 != nil {
|
||||
return model.NewAppError("ExportUsers", "Unable to convert to json", err.Error())
|
||||
return model.NewLocAppError("ExportUsers", "api.export.json.app_error", nil, err.Error())
|
||||
}
|
||||
if _, err3 := usersFile.Write([]byte(result)); err3 != nil {
|
||||
return model.NewAppError("ExportUsers", "Unable to write to export file", err.Error())
|
||||
return model.NewLocAppError("ExportUsers", "api.export.write_file.app_error", nil, err.Error())
|
||||
}
|
||||
}
|
||||
return nil
|
||||
@@ -250,12 +250,12 @@ func ExportUsers(writer ExportWriter, options *ExportOptions, teamId string) *mo
|
||||
func copyDirToExportWriter(writer ExportWriter, inPath string, outPath string) *model.AppError {
|
||||
dir, err := os.Open(inPath)
|
||||
if err != nil {
|
||||
return model.NewAppError("copyDirToExportWriter", "Unable to open directory", err.Error())
|
||||
return model.NewLocAppError("copyDirToExportWriter", "api.export.open_dir.app_error", nil, err.Error())
|
||||
}
|
||||
|
||||
fileInfoList, err := dir.Readdir(0)
|
||||
if err != nil {
|
||||
return model.NewAppError("copyDirToExportWriter", "Unable to read directory", err.Error())
|
||||
return model.NewLocAppError("copyDirToExportWriter", "api.export.read_dir.app_error", nil, err.Error())
|
||||
}
|
||||
|
||||
for _, fileInfo := range fileInfoList {
|
||||
@@ -263,11 +263,11 @@ func copyDirToExportWriter(writer ExportWriter, inPath string, outPath string) *
|
||||
copyDirToExportWriter(writer, inPath+"/"+fileInfo.Name(), outPath+"/"+fileInfo.Name())
|
||||
} else {
|
||||
if toFile, err := writer.Create(outPath + "/" + fileInfo.Name()); err != nil {
|
||||
return model.NewAppError("copyDirToExportWriter", "Unable to open file for export", err.Error())
|
||||
return model.NewLocAppError("copyDirToExportWriter", "api.export.open_file.app_error", nil, err.Error())
|
||||
} else {
|
||||
fromFile, err := os.Open(inPath + "/" + fileInfo.Name())
|
||||
if err != nil {
|
||||
return model.NewAppError("copyDirToExportWriter", "Unable to open file", err.Error())
|
||||
return model.NewLocAppError("copyDirToExportWriter", "api.export.open.app_error", nil, err.Error())
|
||||
}
|
||||
io.Copy(toFile, fromFile)
|
||||
}
|
||||
@@ -281,7 +281,7 @@ func ExportLocalStorage(writer ExportWriter, options *ExportOptions, teamId stri
|
||||
teamDir := utils.Cfg.FileSettings.Directory + "teams/" + teamId
|
||||
|
||||
if utils.Cfg.FileSettings.DriverName == model.IMAGE_DRIVER_S3 {
|
||||
return model.NewAppError("ExportLocalStorage", "S3 is not supported for local storage export.", "")
|
||||
return model.NewLocAppError("ExportLocalStorage", "api.export.s3.app_error", nil, "")
|
||||
} else if utils.Cfg.FileSettings.DriverName == model.IMAGE_DRIVER_LOCAL {
|
||||
if err := copyDirToExportWriter(writer, teamDir, EXPORT_LOCAL_STORAGE_FOLDER); err != nil {
|
||||
return err
|
||||
|
||||
79
api/file.go
79
api/file.go
@@ -58,7 +58,7 @@ const (
|
||||
var fileInfoCache *utils.Cache = utils.NewLru(1000)
|
||||
|
||||
func InitFile(r *mux.Router) {
|
||||
l4g.Debug("Initializing file api routes")
|
||||
l4g.Debug(utils.T("api.file.init.debug"))
|
||||
|
||||
sr := r.PathPrefix("/files").Subrouter()
|
||||
sr.Handle("/upload", ApiUserRequired(uploadFile)).Methods("POST")
|
||||
@@ -70,13 +70,13 @@ func InitFile(r *mux.Router) {
|
||||
|
||||
func uploadFile(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
if len(utils.Cfg.FileSettings.DriverName) == 0 {
|
||||
c.Err = model.NewAppError("uploadFile", "Unable to upload file. Image storage is not configured.", "")
|
||||
c.Err = model.NewLocAppError("uploadFile", "api.file.upload_file.storage.app_error", nil, "")
|
||||
c.Err.StatusCode = http.StatusNotImplemented
|
||||
return
|
||||
}
|
||||
|
||||
if r.ContentLength > model.MAX_FILE_SIZE {
|
||||
c.Err = model.NewAppError("uploadFile", "Unable to upload file. File is too large.", "")
|
||||
c.Err = model.NewLocAppError("uploadFile", "api.file.upload_file.too_large.app_error", nil, "")
|
||||
c.Err.StatusCode = http.StatusRequestEntityTooLarge
|
||||
return
|
||||
}
|
||||
@@ -139,10 +139,10 @@ func uploadFile(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
// Decode image config first to check dimensions before loading the whole thing into memory later on
|
||||
config, _, err := image.DecodeConfig(bytes.NewReader(buf.Bytes()))
|
||||
if err != nil {
|
||||
c.Err = model.NewAppError("uploadFile", "Unable to upload image file.", err.Error())
|
||||
c.Err = model.NewLocAppError("uploadFile", "api.file.upload_file.image.app_error", nil, err.Error())
|
||||
return
|
||||
} else if config.Width*config.Height > MaxImageSize {
|
||||
c.Err = model.NewAppError("uploadFile", "Unable to upload image file. File is too large.", "File exceeds max image size.")
|
||||
c.Err = model.NewLocAppError("uploadFile", "api.file.upload_file.large_image.app_error", nil, c.T("api.file.file_upload.exceeds"))
|
||||
return
|
||||
}
|
||||
}
|
||||
@@ -180,7 +180,7 @@ func handleImagesAndForget(filenames []string, fileData [][]byte, teamId, channe
|
||||
// Decode image bytes into Image object
|
||||
img, imgType, err := image.Decode(bytes.NewReader(fileData[i]))
|
||||
if err != nil {
|
||||
l4g.Error("Unable to decode image channelId=%v userId=%v filename=%v err=%v", channelId, userId, filename, err)
|
||||
l4g.Error(utils.T("api.file.handle_images_forget.decode.error"), channelId, userId, filename, err)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -233,12 +233,12 @@ func handleImagesAndForget(filenames []string, fileData [][]byte, teamId, channe
|
||||
buf := new(bytes.Buffer)
|
||||
err = jpeg.Encode(buf, thumbnail, &jpeg.Options{Quality: 90})
|
||||
if err != nil {
|
||||
l4g.Error("Unable to encode image as jpeg channelId=%v userId=%v filename=%v err=%v", channelId, userId, filename, err)
|
||||
l4g.Error(utils.T("api.file.handle_images_forget.encode_jpeg.error"), channelId, userId, filename, err)
|
||||
return
|
||||
}
|
||||
|
||||
if err := writeFile(buf.Bytes(), dest+name+"_thumb.jpg"); err != nil {
|
||||
l4g.Error("Unable to upload thumbnail channelId=%v userId=%v filename=%v err=%v", channelId, userId, filename, err)
|
||||
l4g.Error(utils.T("api.file.handle_images_forget.upload_thumb.error"), channelId, userId, filename, err)
|
||||
return
|
||||
}
|
||||
}()
|
||||
@@ -256,12 +256,12 @@ func handleImagesAndForget(filenames []string, fileData [][]byte, teamId, channe
|
||||
|
||||
err = jpeg.Encode(buf, preview, &jpeg.Options{Quality: 90})
|
||||
if err != nil {
|
||||
l4g.Error("Unable to encode image as preview jpg channelId=%v userId=%v filename=%v err=%v", channelId, userId, filename, err)
|
||||
l4g.Error(utils.T("api.file.handle_images_forget.encode_preview.error"), channelId, userId, filename, err)
|
||||
return
|
||||
}
|
||||
|
||||
if err := writeFile(buf.Bytes(), dest+name+"_preview.jpg"); err != nil {
|
||||
l4g.Error("Unable to upload preview channelId=%v userId=%v filename=%v err=%v", channelId, userId, filename, err)
|
||||
l4g.Error(utils.T("api.file.handle_images_forget.upload_preview.error"), channelId, userId, filename, err)
|
||||
return
|
||||
}
|
||||
}()
|
||||
@@ -294,7 +294,7 @@ type ImageGetResult struct {
|
||||
|
||||
func getFileInfo(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
if len(utils.Cfg.FileSettings.DriverName) == 0 {
|
||||
c.Err = model.NewAppError("uploadFile", "Unable to get file info. Image storage is not configured.", "")
|
||||
c.Err = model.NewLocAppError("uploadFile", "api.file.upload_file.storage.app_error", nil, "")
|
||||
c.Err.StatusCode = http.StatusNotImplemented
|
||||
return
|
||||
}
|
||||
@@ -351,7 +351,7 @@ func getFileInfo(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
func getFile(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
if len(utils.Cfg.FileSettings.DriverName) == 0 {
|
||||
c.Err = model.NewAppError("uploadFile", "Unable to get file. Image storage is not configured.", "")
|
||||
c.Err = model.NewLocAppError("uploadFile", "api.file.upload_file.storage.app_error", nil, "")
|
||||
c.Err.StatusCode = http.StatusNotImplemented
|
||||
return
|
||||
}
|
||||
@@ -379,6 +379,7 @@ func getFile(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
hash := r.URL.Query().Get("h")
|
||||
data := r.URL.Query().Get("d")
|
||||
teamId := r.URL.Query().Get("t")
|
||||
isDownload := r.URL.Query().Get("download") == "1"
|
||||
|
||||
cchan := Srv.Store.Channel().CheckPermissionsTo(c.Session.TeamId, channelId, c.Session.UserId)
|
||||
|
||||
@@ -394,14 +395,14 @@ func getFile(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
if len(hash) > 0 && len(data) > 0 && len(teamId) == 26 {
|
||||
if !model.ComparePassword(hash, fmt.Sprintf("%v:%v", data, utils.Cfg.FileSettings.PublicLinkSalt)) {
|
||||
c.Err = model.NewAppError("getFile", "The public link does not appear to be valid", "")
|
||||
c.Err = model.NewLocAppError("getFile", "api.file.get_file.public_invalid.app_error", nil, "")
|
||||
return
|
||||
}
|
||||
props := model.MapFromJson(strings.NewReader(data))
|
||||
|
||||
t, err := strconv.ParseInt(props["time"], 10, 64)
|
||||
if err != nil || model.GetMillis()-t > 1000*60*60*24*7 { // one week
|
||||
c.Err = model.NewAppError("getFile", "The public link has expired", "")
|
||||
c.Err = model.NewLocAppError("getFile", "api.file.get_file.public_expired.app_error", nil, "")
|
||||
return
|
||||
}
|
||||
} else if !c.HasPermissionsToChannel(cchan, "getFile") {
|
||||
@@ -411,7 +412,7 @@ func getFile(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
f := <-fileData
|
||||
|
||||
if f == nil {
|
||||
c.Err = model.NewAppError("getFile", "Could not find file.", "path="+path)
|
||||
c.Err = model.NewLocAppError("getFile", "api.file.get_file.not_found.app_error", nil, "path="+path)
|
||||
c.Err.StatusCode = http.StatusNotFound
|
||||
return
|
||||
}
|
||||
@@ -420,16 +421,18 @@ func getFile(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Length", strconv.Itoa(len(f)))
|
||||
w.Header().Del("Content-Type") // Content-Type will be set automatically by the http writer
|
||||
|
||||
// attach extra headers to trigger a download on IE, Edge, and Safari
|
||||
ua := user_agent.New(r.UserAgent())
|
||||
bname, _ := ua.Browser()
|
||||
if isDownload {
|
||||
// attach extra headers to trigger a download on IE, Edge, and Safari
|
||||
ua := user_agent.New(r.UserAgent())
|
||||
bname, _ := ua.Browser()
|
||||
|
||||
if bname == "Edge" || bname == "Internet Explorer" || bname == "Safari" {
|
||||
// trim off anything before the final / so we just get the file's name
|
||||
parts := strings.Split(filename, "/")
|
||||
if bname == "Edge" || bname == "Internet Explorer" || bname == "Safari" {
|
||||
// trim off anything before the final / so we just get the file's name
|
||||
parts := strings.Split(filename, "/")
|
||||
|
||||
w.Header().Set("Content-Type", "application/octet-stream")
|
||||
w.Header().Set("Content-Disposition", "attachment;filename=\""+parts[len(parts)-1]+"\"")
|
||||
w.Header().Set("Content-Type", "application/octet-stream")
|
||||
w.Header().Set("Content-Disposition", "attachment;filename=\""+parts[len(parts)-1]+"\"")
|
||||
}
|
||||
}
|
||||
|
||||
w.Write(f)
|
||||
@@ -449,13 +452,13 @@ func getFileAndForget(path string, fileData chan []byte) {
|
||||
|
||||
func getPublicLink(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
if len(utils.Cfg.FileSettings.DriverName) == 0 {
|
||||
c.Err = model.NewAppError("uploadFile", "Unable to get link. Image storage is not configured.", "")
|
||||
c.Err = model.NewLocAppError("uploadFile", "api.file.upload_file.storage.app_error", nil, "")
|
||||
c.Err.StatusCode = http.StatusNotImplemented
|
||||
return
|
||||
}
|
||||
|
||||
if !utils.Cfg.FileSettings.EnablePublicLink {
|
||||
c.Err = model.NewAppError("getPublicLink", "Public links have been disabled", "")
|
||||
c.Err = model.NewLocAppError("getPublicLink", "api.file.get_public_link.disabled.app_error", nil, "")
|
||||
c.Err.StatusCode = http.StatusForbidden
|
||||
}
|
||||
|
||||
@@ -500,13 +503,13 @@ func getPublicLink(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
func getExport(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
if !c.HasPermissionsToTeam(c.Session.TeamId, "export") || !c.IsTeamAdmin() {
|
||||
c.Err = model.NewAppError("getExport", "Only a team admin can retrieve exported data.", "userId="+c.Session.UserId)
|
||||
c.Err = model.NewLocAppError("getExport", "api.file.get_export.team_admin.app_error", nil, "userId="+c.Session.UserId)
|
||||
c.Err.StatusCode = http.StatusForbidden
|
||||
return
|
||||
}
|
||||
data, err := readFile(EXPORT_PATH + EXPORT_FILENAME)
|
||||
if err != nil {
|
||||
c.Err = model.NewAppError("getExport", "Unable to retrieve exported file. Please re-export", err.Error())
|
||||
c.Err = model.NewLocAppError("getExport", "api.file.get_export.retrieve.app_error", nil, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
@@ -538,14 +541,14 @@ func writeFile(f []byte, path string) *model.AppError {
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return model.NewAppError("writeFile", "Encountered an error writing to S3", err.Error())
|
||||
return model.NewLocAppError("writeFile", "api.file.write_file.s3.app_error", nil, err.Error())
|
||||
}
|
||||
} else if utils.Cfg.FileSettings.DriverName == model.IMAGE_DRIVER_LOCAL {
|
||||
if err := writeFileLocally(f, utils.Cfg.FileSettings.Directory+path); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
return model.NewAppError("writeFile", "File storage not configured properly. Please configure for either S3 or local server file storage.", "")
|
||||
return model.NewLocAppError("writeFile", "api.file.write_file.configured.app_error", nil, "")
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -553,11 +556,11 @@ func writeFile(f []byte, path string) *model.AppError {
|
||||
|
||||
func writeFileLocally(f []byte, path string) *model.AppError {
|
||||
if err := os.MkdirAll(filepath.Dir(path), 0774); err != nil {
|
||||
return model.NewAppError("writeFile", "Encountered an error creating the directory for the new file", err.Error())
|
||||
return model.NewLocAppError("writeFile", "api.file.write_file_locally.create_dir.app_error", nil, err.Error())
|
||||
}
|
||||
|
||||
if err := ioutil.WriteFile(path, f, 0644); err != nil {
|
||||
return model.NewAppError("writeFile", "Encountered an error writing to local server storage", err.Error())
|
||||
return model.NewLocAppError("writeFile", "api.file.write_file_locally.writing.app_error", nil, err.Error())
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -583,31 +586,31 @@ func readFile(path string) ([]byte, *model.AppError) {
|
||||
if f != nil {
|
||||
return f, nil
|
||||
} else if tries >= 3 {
|
||||
return nil, model.NewAppError("readFile", "Unable to get file from S3", "path="+path+", err="+err.Error())
|
||||
return nil, model.NewLocAppError("readFile", "api.file.read_file.get.app_error", nil, "path="+path+", err="+err.Error())
|
||||
}
|
||||
time.Sleep(3000 * time.Millisecond)
|
||||
}
|
||||
} else if utils.Cfg.FileSettings.DriverName == model.IMAGE_DRIVER_LOCAL {
|
||||
if f, err := ioutil.ReadFile(utils.Cfg.FileSettings.Directory + path); err != nil {
|
||||
return nil, model.NewAppError("readFile", "Encountered an error reading from local server storage", err.Error())
|
||||
return nil, model.NewLocAppError("readFile", "api.file.read_file.reading_local.app_error", nil, err.Error())
|
||||
} else {
|
||||
return f, nil
|
||||
}
|
||||
} else {
|
||||
return nil, model.NewAppError("readFile", "File storage not configured properly. Please configure for either S3 or local server file storage.", "")
|
||||
return nil, model.NewLocAppError("readFile", "api.file.read_file.configured.app_error", nil, "")
|
||||
}
|
||||
}
|
||||
|
||||
func openFileWriteStream(path string) (io.Writer, *model.AppError) {
|
||||
if utils.Cfg.FileSettings.DriverName == model.IMAGE_DRIVER_S3 {
|
||||
return nil, model.NewAppError("openFileWriteStream", "S3 is not supported.", "")
|
||||
return nil, model.NewLocAppError("openFileWriteStream", "api.file.open_file_write_stream.s3.app_error", nil, "")
|
||||
} else if utils.Cfg.FileSettings.DriverName == model.IMAGE_DRIVER_LOCAL {
|
||||
if err := os.MkdirAll(filepath.Dir(utils.Cfg.FileSettings.Directory+path), 0774); err != nil {
|
||||
return nil, model.NewAppError("openFileWriteStream", "Encountered an error creating the directory for the new file", err.Error())
|
||||
return nil, model.NewLocAppError("openFileWriteStream", "api.file.open_file_write_stream.creating_dir.app_error", nil, err.Error())
|
||||
}
|
||||
|
||||
if fileHandle, err := os.Create(utils.Cfg.FileSettings.Directory + path); err != nil {
|
||||
return nil, model.NewAppError("openFileWriteStream", "Encountered an error writing to local server storage", err.Error())
|
||||
return nil, model.NewLocAppError("openFileWriteStream", "api.file.open_file_write_stream.local_server.app_error", nil, err.Error())
|
||||
} else {
|
||||
fileHandle.Chmod(0644)
|
||||
return fileHandle, nil
|
||||
@@ -615,7 +618,7 @@ func openFileWriteStream(path string) (io.Writer, *model.AppError) {
|
||||
|
||||
}
|
||||
|
||||
return nil, model.NewAppError("openFileWriteStream", "File storage not configured properly. Please configure for either S3 or local server file storage.", "")
|
||||
return nil, model.NewLocAppError("openFileWriteStream", "api.file.open_file_write_stream.configured.app_error", nil, "")
|
||||
}
|
||||
|
||||
func closeFileWriteStream(file io.Writer) {
|
||||
|
||||
@@ -6,6 +6,7 @@ package api
|
||||
import (
|
||||
l4g "github.com/alecthomas/log4go"
|
||||
"github.com/mattermost/platform/model"
|
||||
"github.com/mattermost/platform/utils"
|
||||
)
|
||||
|
||||
//
|
||||
@@ -17,7 +18,7 @@ func ImportPost(post *model.Post) {
|
||||
post.Hashtags, _ = model.ParseHashtags(post.Message)
|
||||
|
||||
if result := <-Srv.Store.Post().Save(post); result.Err != nil {
|
||||
l4g.Debug("Error saving post. user=" + post.UserId + ", message=" + post.Message)
|
||||
l4g.Debug(utils.T("api.import.import_post.saving.debug"), post.UserId, post.Message)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,17 +26,17 @@ func ImportUser(user *model.User) *model.User {
|
||||
user.MakeNonNil()
|
||||
|
||||
if result := <-Srv.Store.User().Save(user); result.Err != nil {
|
||||
l4g.Error("Error saving user. err=%v", result.Err)
|
||||
l4g.Error(utils.T("api.import.import_user.saving.error"), result.Err)
|
||||
return nil
|
||||
} else {
|
||||
ruser := result.Data.(*model.User)
|
||||
|
||||
if err := JoinDefaultChannels(ruser, ""); err != nil {
|
||||
l4g.Error("Encountered an issue joining default channels user_id=%s, team_id=%s, err=%v", ruser.Id, ruser.TeamId, err)
|
||||
l4g.Error(utils.T("api.import.import_user.joining_default.error"), ruser.Id, ruser.TeamId, err)
|
||||
}
|
||||
|
||||
if cresult := <-Srv.Store.User().VerifyEmail(ruser.Id); cresult.Err != nil {
|
||||
l4g.Error("Failed to set email verified err=%v", cresult.Err)
|
||||
l4g.Error(utils.T("api.import.import_user.set_email.error"), cresult.Err)
|
||||
}
|
||||
|
||||
return ruser
|
||||
|
||||
@@ -15,7 +15,7 @@ import (
|
||||
)
|
||||
|
||||
func InitLicense(r *mux.Router) {
|
||||
l4g.Debug("Initializing license api routes")
|
||||
l4g.Debug(utils.T("api.license.init.debug"))
|
||||
|
||||
sr := r.PathPrefix("/license").Subrouter()
|
||||
sr.Handle("/add", ApiAdminSystemRequired(addLicense)).Methods("POST")
|
||||
@@ -34,13 +34,13 @@ func addLicense(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
fileArray, ok := m.File["license"]
|
||||
if !ok {
|
||||
c.Err = model.NewAppError("addLicense", "No file under 'license' in request", "")
|
||||
c.Err = model.NewLocAppError("addLicense", "api.license.add_license.no_file.app_error", nil, "")
|
||||
c.Err.StatusCode = http.StatusBadRequest
|
||||
return
|
||||
}
|
||||
|
||||
if len(fileArray) <= 0 {
|
||||
c.Err = model.NewAppError("addLicense", "Empty array under 'license' in request", "")
|
||||
c.Err = model.NewLocAppError("addLicense", "api.license.add_license.array.app_error", nil, "")
|
||||
c.Err.StatusCode = http.StatusBadRequest
|
||||
return
|
||||
}
|
||||
@@ -50,7 +50,7 @@ func addLicense(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
file, err := fileData.Open()
|
||||
defer file.Close()
|
||||
if err != nil {
|
||||
c.Err = model.NewAppError("addLicense", "Could not open license file", err.Error())
|
||||
c.Err = model.NewLocAppError("addLicense", "api.license.add_license.open.app_error", nil, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
@@ -65,19 +65,19 @@ func addLicense(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
if ok := utils.SetLicense(license); !ok {
|
||||
c.LogAudit("failed - expired or non-started license")
|
||||
c.Err = model.NewAppError("addLicense", "License is either expired or has not yet started.", "")
|
||||
c.Err = model.NewLocAppError("addLicense", "api.license.add_license.expired.app_error", nil, "")
|
||||
return
|
||||
}
|
||||
|
||||
if err := writeFileLocally(data, utils.LicenseLocation()); err != nil {
|
||||
c.LogAudit("failed - could not save license file")
|
||||
c.Err = model.NewAppError("addLicense", "License did not save properly.", "path="+utils.LicenseLocation())
|
||||
c.Err = model.NewLocAppError("addLicense", "api.license.add_license.save.app_error", nil, "path="+utils.LicenseLocation())
|
||||
utils.RemoveLicense()
|
||||
return
|
||||
}
|
||||
} else {
|
||||
c.LogAudit("failed - invalid license")
|
||||
c.Err = model.NewAppError("addLicense", "Invalid license file.", "")
|
||||
c.Err = model.NewLocAppError("addLicense", "api.license.add_license.invalid.app_error", nil, "")
|
||||
return
|
||||
}
|
||||
|
||||
@@ -90,7 +90,7 @@ func removeLicense(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
if ok := utils.RemoveLicense(); !ok {
|
||||
c.LogAudit("failed - could not remove license file")
|
||||
c.Err = model.NewAppError("removeLicense", "License did not remove properly.", "")
|
||||
c.Err = model.NewLocAppError("removeLicense", "api.license.remove_license.remove.app_error", nil, "")
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
26
api/oauth.go
26
api/oauth.go
@@ -14,7 +14,7 @@ import (
|
||||
)
|
||||
|
||||
func InitOAuth(r *mux.Router) {
|
||||
l4g.Debug("Initializing oauth api routes")
|
||||
l4g.Debug(utils.T("api.oauth.init.debug"))
|
||||
|
||||
sr := r.PathPrefix("/oauth").Subrouter()
|
||||
|
||||
@@ -24,7 +24,7 @@ func InitOAuth(r *mux.Router) {
|
||||
|
||||
func registerOAuthApp(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
if !utils.Cfg.ServiceSettings.EnableOAuthServiceProvider {
|
||||
c.Err = model.NewAppError("registerOAuthApp", "The system admin has turned off OAuth service providing.", "")
|
||||
c.Err = model.NewLocAppError("registerOAuthApp", "api.oauth.register_oauth_app.turn_off.app_error", nil, "")
|
||||
c.Err.StatusCode = http.StatusNotImplemented
|
||||
return
|
||||
}
|
||||
@@ -58,7 +58,7 @@ func registerOAuthApp(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
func allowOAuth(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
if !utils.Cfg.ServiceSettings.EnableOAuthServiceProvider {
|
||||
c.Err = model.NewAppError("allowOAuth", "The system admin has turned off OAuth service providing.", "")
|
||||
c.Err = model.NewLocAppError("allowOAuth", "api.oauth.allow_oauth.turn_off.app_error", nil, "")
|
||||
c.Err.StatusCode = http.StatusNotImplemented
|
||||
return
|
||||
}
|
||||
@@ -70,19 +70,19 @@ func allowOAuth(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
responseType := r.URL.Query().Get("response_type")
|
||||
if len(responseType) == 0 {
|
||||
c.Err = model.NewAppError("allowOAuth", "invalid_request: Bad response_type", "")
|
||||
c.Err = model.NewLocAppError("allowOAuth", "api.oauth.allow_oauth.bad_response.app_error", nil, "")
|
||||
return
|
||||
}
|
||||
|
||||
clientId := r.URL.Query().Get("client_id")
|
||||
if len(clientId) != 26 {
|
||||
c.Err = model.NewAppError("allowOAuth", "invalid_request: Bad client_id", "")
|
||||
c.Err = model.NewLocAppError("allowOAuth", "api.oauth.allow_oauth.bad_client.app_error", nil, "")
|
||||
return
|
||||
}
|
||||
|
||||
redirectUri := r.URL.Query().Get("redirect_uri")
|
||||
if len(redirectUri) == 0 {
|
||||
c.Err = model.NewAppError("allowOAuth", "invalid_request: Missing or bad redirect_uri", "")
|
||||
c.Err = model.NewLocAppError("allowOAuth", "api.oauth.allow_oauth.bad_redirect.app_error", nil, "")
|
||||
return
|
||||
}
|
||||
|
||||
@@ -91,7 +91,7 @@ func allowOAuth(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
var app *model.OAuthApp
|
||||
if result := <-Srv.Store.OAuth().GetApp(clientId); result.Err != nil {
|
||||
c.Err = model.NewAppError("allowOAuth", "server_error: Error accessing the database", "")
|
||||
c.Err = model.NewLocAppError("allowOAuth", "api.oauth.allow_oauth.database.app_error", nil, "")
|
||||
return
|
||||
} else {
|
||||
app = result.Data.(*model.OAuthApp)
|
||||
@@ -99,7 +99,7 @@ func allowOAuth(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
if !app.IsValidRedirectURL(redirectUri) {
|
||||
c.LogAudit("fail - redirect_uri did not match registered callback")
|
||||
c.Err = model.NewAppError("allowOAuth", "invalid_request: Supplied redirect_uri did not match registered callback_url", "")
|
||||
c.Err = model.NewLocAppError("allowOAuth", "api.oauth.allow_oauth.redirect_callback.app_error", nil, "")
|
||||
return
|
||||
}
|
||||
|
||||
@@ -132,7 +132,7 @@ func RevokeAccessToken(token string) *model.AppError {
|
||||
|
||||
var accessData *model.AccessData
|
||||
if result := <-Srv.Store.OAuth().GetAccessData(token); result.Err != nil {
|
||||
return model.NewAppError("RevokeAccessToken", "Error getting access token from DB before deletion", "")
|
||||
return model.NewLocAppError("RevokeAccessToken", "api.oauth.revoke_access_token.get.app_error", nil, "")
|
||||
} else {
|
||||
accessData = result.Data.(*model.AccessData)
|
||||
}
|
||||
@@ -141,15 +141,15 @@ func RevokeAccessToken(token string) *model.AppError {
|
||||
cchan := Srv.Store.OAuth().RemoveAuthData(accessData.AuthCode)
|
||||
|
||||
if result := <-tchan; result.Err != nil {
|
||||
return model.NewAppError("RevokeAccessToken", "Error deleting access token from DB", "")
|
||||
return model.NewLocAppError("RevokeAccessToken", "api.oauth.revoke_access_token.del_token.app_error", nil, "")
|
||||
}
|
||||
|
||||
if result := <-cchan; result.Err != nil {
|
||||
return model.NewAppError("RevokeAccessToken", "Error deleting authorization code from DB", "")
|
||||
return model.NewLocAppError("RevokeAccessToken", "api.oauth.revoke_access_token.del_code.app_error", nil, "")
|
||||
}
|
||||
|
||||
if result := <-schan; result.Err != nil {
|
||||
return model.NewAppError("RevokeAccessToken", "Error deleting session from DB", "")
|
||||
return model.NewLocAppError("RevokeAccessToken", "api.oauth.revoke_access_token.del_session.app_error", nil, "")
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -157,7 +157,7 @@ func RevokeAccessToken(token string) *model.AppError {
|
||||
|
||||
func GetAuthData(code string) *model.AuthData {
|
||||
if result := <-Srv.Store.OAuth().GetAuthData(code); result.Err != nil {
|
||||
l4g.Error("Couldn't find auth code for code=%s", code)
|
||||
l4g.Error(utils.T("api.oauth.get_auth_data.find.error"), code)
|
||||
return nil
|
||||
} else {
|
||||
return result.Data.(*model.AuthData)
|
||||
|
||||
137
api/post.go
137
api/post.go
@@ -20,7 +20,7 @@ import (
|
||||
)
|
||||
|
||||
func InitPost(r *mux.Router) {
|
||||
l4g.Debug("Initializing post api routes")
|
||||
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")
|
||||
@@ -53,14 +53,16 @@ func createPost(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
if rp, err := CreatePost(c, post, true); err != nil {
|
||||
c.Err = err
|
||||
|
||||
if strings.Contains(c.Err.Message, "parameter") {
|
||||
if c.Err.Id == "api.post.create_post.root_id.app_error" ||
|
||||
c.Err.Id == "api.post.create_post.channel_root_id.app_error" ||
|
||||
c.Err.Id == "api.post.create_post.parent_id.app_error" {
|
||||
c.Err.StatusCode = http.StatusBadRequest
|
||||
}
|
||||
|
||||
return
|
||||
} else {
|
||||
if result := <-Srv.Store.Channel().UpdateLastViewedAt(post.ChannelId, c.Session.UserId); result.Err != nil {
|
||||
l4g.Error("Encountered error updating last viewed, channel_id=%s, user_id=%s, err=%v", post.ChannelId, c.Session.UserId, result.Err)
|
||||
l4g.Error(utils.T("api.post.create_post.last_viewed.error"), post.ChannelId, c.Session.UserId, result.Err)
|
||||
}
|
||||
|
||||
w.Write([]byte(rp.ToJson()))
|
||||
@@ -76,11 +78,11 @@ func CreatePost(c *Context, post *model.Post, triggerWebhooks bool) (*model.Post
|
||||
// Verify the parent/child relationships are correct
|
||||
if pchan != nil {
|
||||
if presult := <-pchan; presult.Err != nil {
|
||||
return nil, model.NewAppError("createPost", "Invalid RootId parameter", "")
|
||||
return nil, model.NewLocAppError("createPost", "api.post.create_post.root_id.app_error", nil, "")
|
||||
} else {
|
||||
list := presult.Data.(*model.PostList)
|
||||
if len(list.Posts) == 0 || !list.IsChannelId(post.ChannelId) {
|
||||
return nil, model.NewAppError("createPost", "Invalid ChannelId for RootId parameter", "")
|
||||
return nil, model.NewLocAppError("createPost", "api.post.create_post.channel_root_id.app_error", nil, "")
|
||||
}
|
||||
|
||||
if post.ParentId == "" {
|
||||
@@ -90,7 +92,7 @@ func CreatePost(c *Context, post *model.Post, triggerWebhooks bool) (*model.Post
|
||||
if post.RootId != post.ParentId {
|
||||
parent := list.Posts[post.ParentId]
|
||||
if parent == nil {
|
||||
return nil, model.NewAppError("createPost", "Invalid ParentId parameter", "")
|
||||
return nil, model.NewLocAppError("createPost", "api.post.create_post.parent_id.app_error", nil, "")
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -129,7 +131,7 @@ func CreatePost(c *Context, post *model.Post, triggerWebhooks bool) (*model.Post
|
||||
doRemove = true
|
||||
}
|
||||
if doRemove {
|
||||
l4g.Error("Bad filename discarded, filename=%v", path)
|
||||
l4g.Error(utils.T("api.post.create_post.bad_filename.error"), path)
|
||||
post.Filenames = append(post.Filenames[:i], post.Filenames[i+1:]...)
|
||||
}
|
||||
}
|
||||
@@ -185,6 +187,28 @@ func CreateWebhookPost(c *Context, channelId, text, overrideUsername, overrideIc
|
||||
attachment["text"] = aText
|
||||
list[i] = attachment
|
||||
}
|
||||
if _, ok := attachment["pretext"]; ok {
|
||||
aText := attachment["pretext"].(string)
|
||||
aText = linkWithTextRegex.ReplaceAllString(aText, "[${2}](${1})")
|
||||
attachment["pretext"] = aText
|
||||
list[i] = attachment
|
||||
}
|
||||
if fVal, ok := attachment["fields"]; ok {
|
||||
if fields, ok := fVal.([]interface{}); ok {
|
||||
// parse attachment field links into Markdown format
|
||||
for j, fInt := range fields {
|
||||
field := fInt.(map[string]interface{})
|
||||
if _, ok := field["text"]; ok {
|
||||
fText := field["text"].(string)
|
||||
fText = linkWithTextRegex.ReplaceAllString(fText, "[${2}](${1})")
|
||||
field["text"] = fText
|
||||
fields[j] = field
|
||||
}
|
||||
}
|
||||
attachment["fields"] = fields
|
||||
list[i] = attachment
|
||||
}
|
||||
}
|
||||
}
|
||||
post.AddProp(key, list)
|
||||
}
|
||||
@@ -195,7 +219,7 @@ func CreateWebhookPost(c *Context, channelId, text, overrideUsername, overrideIc
|
||||
}
|
||||
|
||||
if _, err := CreatePost(c, post, false); err != nil {
|
||||
return nil, model.NewAppError("CreateWebhookPost", "Error creating post", "err="+err.Message)
|
||||
return nil, model.NewLocAppError("CreateWebhookPost", "api.post.create_webhook_post.creating.app_error", nil, "err="+err.Message)
|
||||
}
|
||||
|
||||
return post, nil
|
||||
@@ -209,7 +233,7 @@ func handlePostEventsAndForget(c *Context, post *model.Post, triggerWebhooks boo
|
||||
|
||||
var team *model.Team
|
||||
if result := <-tchan; result.Err != nil {
|
||||
l4g.Error("Encountered error getting team, team_id=%s, err=%v", c.Session.TeamId, result.Err)
|
||||
l4g.Error(utils.T("api.post.handle_post_events_and_forget.team.error"), c.Session.TeamId, result.Err)
|
||||
return
|
||||
} else {
|
||||
team = result.Data.(*model.Team)
|
||||
@@ -217,7 +241,7 @@ func handlePostEventsAndForget(c *Context, post *model.Post, triggerWebhooks boo
|
||||
|
||||
var channel *model.Channel
|
||||
if result := <-cchan; result.Err != nil {
|
||||
l4g.Error("Encountered error getting channel, channel_id=%s, err=%v", post.ChannelId, result.Err)
|
||||
l4g.Error(utils.T("api.post.handle_post_events_and_forget.channel.error"), post.ChannelId, result.Err)
|
||||
return
|
||||
} else {
|
||||
channel = result.Data.(*model.Channel)
|
||||
@@ -227,7 +251,7 @@ func handlePostEventsAndForget(c *Context, post *model.Post, triggerWebhooks boo
|
||||
|
||||
var user *model.User
|
||||
if result := <-uchan; result.Err != nil {
|
||||
l4g.Error("Encountered error getting user, user_id=%s, err=%v", post.UserId, result.Err)
|
||||
l4g.Error(utils.T("api.post.handle_post_events_and_forget.user.error"), post.UserId, result.Err)
|
||||
return
|
||||
} else {
|
||||
user = result.Data.(*model.User)
|
||||
@@ -246,14 +270,14 @@ func handlePostEventsAndForget(c *Context, post *model.Post, triggerWebhooks boo
|
||||
func makeDirectChannelVisible(teamId string, channelId string) {
|
||||
var members []model.ChannelMember
|
||||
if result := <-Srv.Store.Channel().GetMembers(channelId); result.Err != nil {
|
||||
l4g.Error("Failed to get channel members channel_id=%v err=%v", channelId, result.Err.Message)
|
||||
l4g.Error(utils.T("api.post.make_direct_channel_visible.get_members.error"), channelId, result.Err.Message)
|
||||
return
|
||||
} else {
|
||||
members = result.Data.([]model.ChannelMember)
|
||||
}
|
||||
|
||||
if len(members) != 2 {
|
||||
l4g.Error("Failed to get 2 members for a direct channel channel_id=%v", channelId)
|
||||
l4g.Error(utils.T("api.post.make_direct_channel_visible.get_2_members.error"), channelId)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -271,7 +295,7 @@ func makeDirectChannelVisible(teamId string, channelId string) {
|
||||
}
|
||||
|
||||
if saveResult := <-Srv.Store.Preference().Save(&model.Preferences{*preference}); saveResult.Err != nil {
|
||||
l4g.Error("Failed to save direct channel preference user_id=%v other_user_id=%v err=%v", member.UserId, otherUserId, saveResult.Err.Message)
|
||||
l4g.Error(utils.T("api.post.make_direct_channel_visible.save_pref.error"), member.UserId, otherUserId, saveResult.Err.Message)
|
||||
} else {
|
||||
message := model.NewMessage(teamId, channelId, member.UserId, model.ACTION_PREFERENCE_CHANGED)
|
||||
message.Add("preference", preference.ToJson())
|
||||
@@ -286,7 +310,7 @@ func makeDirectChannelVisible(teamId string, channelId string) {
|
||||
preference.Value = "true"
|
||||
|
||||
if updateResult := <-Srv.Store.Preference().Save(&model.Preferences{preference}); updateResult.Err != nil {
|
||||
l4g.Error("Failed to update direct channel preference user_id=%v other_user_id=%v err=%v", member.UserId, otherUserId, updateResult.Err.Message)
|
||||
l4g.Error(utils.T("api.post.make_direct_channel_visible.update_pref.error"), member.UserId, otherUserId, updateResult.Err.Message)
|
||||
} else {
|
||||
message := model.NewMessage(teamId, channelId, member.UserId, model.ACTION_PREFERENCE_CHANGED)
|
||||
message.Add("preference", preference.ToJson())
|
||||
@@ -313,7 +337,7 @@ func handleWebhookEventsAndForget(c *Context, post *model.Post, team *model.Team
|
||||
hooks := []*model.OutgoingWebhook{}
|
||||
|
||||
if result := <-hchan; result.Err != nil {
|
||||
l4g.Error("Encountered error getting webhooks by team, err=%v", result.Err)
|
||||
l4g.Error(utils.T("api.post.handle_webhook_events_and_forget.getting.error"), result.Err)
|
||||
return
|
||||
} else {
|
||||
hooks = result.Data.([]*model.OutgoingWebhook)
|
||||
@@ -364,17 +388,17 @@ func handleWebhookEventsAndForget(c *Context, post *model.Post, team *model.Team
|
||||
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
|
||||
req.Header.Set("Accept", "application/json")
|
||||
if resp, err := client.Do(req); err != nil {
|
||||
l4g.Error("Event POST failed, err=%s", err.Error())
|
||||
l4g.Error(utils.T("api.post.handle_webhook_events_and_forget.event_post.error"), err.Error())
|
||||
} else {
|
||||
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, 0}
|
||||
newContext := &Context{mockSession, model.NewId(), "", c.Path, nil, c.teamURLValid, c.teamURL, c.siteURL, 0, c.T, c.Locale}
|
||||
|
||||
if text, ok := respProps["text"]; ok {
|
||||
if _, err := CreateWebhookPost(newContext, post.ChannelId, text, respProps["username"], respProps["icon_url"], post.Props, post.Type); err != nil {
|
||||
l4g.Error("Failed to create response post, err=%v", err)
|
||||
l4g.Error(utils.T("api.post.handle_webhook_events_and_forget.create_post.error"), err)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -398,25 +422,17 @@ func sendNotificationsAndForget(c *Context, post *model.Post, team *model.Team,
|
||||
var channelName string
|
||||
var bodyText string
|
||||
var subjectText string
|
||||
if channel.Type == model.CHANNEL_DIRECT {
|
||||
bodyText = "You have one new message."
|
||||
subjectText = "New Direct Message"
|
||||
} else {
|
||||
bodyText = "You have one new mention."
|
||||
subjectText = "New Mention"
|
||||
channelName = channel.DisplayName
|
||||
}
|
||||
|
||||
var mentionedUsers []string
|
||||
|
||||
if result := <-uchan; result.Err != nil {
|
||||
l4g.Error("Failed to retrieve user profiles team_id=%v, err=%v", c.Session.TeamId, result.Err)
|
||||
l4g.Error(utils.T("api.post.send_notifications_and_forget.retrive_profiles.error"), c.Session.TeamId, result.Err)
|
||||
return
|
||||
} else {
|
||||
profileMap := result.Data.(map[string]*model.User)
|
||||
|
||||
if _, ok := profileMap[post.UserId]; !ok {
|
||||
l4g.Error("Post user_id not returned by GetProfiles user_id=%v", post.UserId)
|
||||
l4g.Error(utils.T("api.post.send_notifications_and_forget.user_id.error"), post.UserId)
|
||||
return
|
||||
}
|
||||
senderName := profileMap[post.UserId].Username
|
||||
@@ -447,7 +463,7 @@ func sendNotificationsAndForget(c *Context, post *model.Post, team *model.Team,
|
||||
|
||||
// Find out who is a member of the channel, only keep those profiles
|
||||
if eResult := <-echan; eResult.Err != nil {
|
||||
l4g.Error("Failed to get channel members channel_id=%v err=%v", post.ChannelId, eResult.Err.Message)
|
||||
l4g.Error(utils.T("api.post.send_notifications_and_forget.members.error"), post.ChannelId, eResult.Err.Message)
|
||||
return
|
||||
} else {
|
||||
tempProfileMap := make(map[string]*model.User)
|
||||
@@ -555,14 +571,6 @@ func sendNotificationsAndForget(c *Context, post *model.Post, team *model.Team,
|
||||
// Build and send the emails
|
||||
tm := time.Unix(post.CreateAt/1000, 0)
|
||||
|
||||
subjectPage := NewServerTemplatePage("post_subject")
|
||||
subjectPage.Props["SiteURL"] = c.GetSiteURL()
|
||||
subjectPage.Props["TeamDisplayName"] = team.DisplayName
|
||||
subjectPage.Props["SubjectText"] = subjectText
|
||||
subjectPage.Props["Month"] = tm.Month().String()[:3]
|
||||
subjectPage.Props["Day"] = fmt.Sprintf("%d", tm.Day())
|
||||
subjectPage.Props["Year"] = fmt.Sprintf("%d", tm.Year())
|
||||
|
||||
for id, doSend := range toEmailMap {
|
||||
|
||||
if !doSend {
|
||||
@@ -574,6 +582,25 @@ func sendNotificationsAndForget(c *Context, post *model.Post, team *model.Team,
|
||||
continue
|
||||
}
|
||||
|
||||
userLocale := utils.GetUserTranslations(profileMap[id].Locale)
|
||||
|
||||
if channel.Type == model.CHANNEL_DIRECT {
|
||||
bodyText = userLocale("api.post.send_notifications_and_forget.message_body")
|
||||
subjectText = userLocale("api.post.send_notifications_and_forget.message_subject")
|
||||
} else {
|
||||
bodyText = userLocale("api.post.send_notifications_and_forget.mention_body")
|
||||
subjectText = userLocale("api.post.send_notifications_and_forget.mention_subject")
|
||||
channelName = channel.DisplayName
|
||||
}
|
||||
|
||||
subjectPage := NewServerTemplatePage("post_subject")
|
||||
subjectPage.Props["SiteURL"] = c.GetSiteURL()
|
||||
subjectPage.Props["TeamDisplayName"] = team.DisplayName
|
||||
subjectPage.Props["SubjectText"] = subjectText
|
||||
subjectPage.Props["Month"] = tm.Month().String()[:3]
|
||||
subjectPage.Props["Day"] = fmt.Sprintf("%d", tm.Day())
|
||||
subjectPage.Props["Year"] = fmt.Sprintf("%d", tm.Year())
|
||||
|
||||
bodyPage := NewServerTemplatePage("post_body")
|
||||
bodyPage.Props["SiteURL"] = c.GetSiteURL()
|
||||
bodyPage.Props["Nickname"] = profileMap[id].FirstName
|
||||
@@ -616,17 +643,18 @@ func sendNotificationsAndForget(c *Context, post *model.Post, team *model.Team,
|
||||
attachmentPrefix += "s"
|
||||
}
|
||||
|
||||
bodyPage.Props["PostMessage"] = fmt.Sprintf("%s: %s sent", attachmentPrefix, filenamesString)
|
||||
bodyPage.Props["PostMessage"] = userLocale("api.post.send_notifications_and_forget.sent",
|
||||
map[string]interface{}{"Prefix": attachmentPrefix, "Filenames": filenamesString})
|
||||
}
|
||||
|
||||
if err := utils.SendMail(profileMap[id].Email, subjectPage.Render(), bodyPage.Render()); err != nil {
|
||||
l4g.Error("Failed to send mention email successfully email=%v err=%v", profileMap[id].Email, err)
|
||||
l4g.Error(utils.T("api.post.send_notifications_and_forget.send.error"), profileMap[id].Email, err)
|
||||
}
|
||||
|
||||
if *utils.Cfg.EmailSettings.SendPushNotifications {
|
||||
sessionChan := Srv.Store.Session().GetSessions(id)
|
||||
if result := <-sessionChan; result.Err != nil {
|
||||
l4g.Error("Failed to retrieve sessions in notifications id=%v, err=%v", id, result.Err)
|
||||
l4g.Error(utils.T("api.post.send_notifications_and_forget.sessions.error"), id, result.Err)
|
||||
} else {
|
||||
sessions := result.Data.([]*model.Session)
|
||||
alreadySeen := make(map[string]string)
|
||||
@@ -649,17 +677,17 @@ func sendNotificationsAndForget(c *Context, post *model.Post, team *model.Team,
|
||||
}
|
||||
|
||||
if channel.Type == model.CHANNEL_DIRECT {
|
||||
msg.Message = senderName + " sent you a direct message"
|
||||
msg.Message = senderName + userLocale("api.post.send_notifications_and_forget.push_message")
|
||||
} else {
|
||||
msg.Message = senderName + " mentioned you in " + channelName
|
||||
msg.Message = senderName + userLocale("api.post.send_notifications_and_forget.push_mention") + channelName
|
||||
}
|
||||
|
||||
httpClient := http.Client{}
|
||||
request, _ := http.NewRequest("POST", *utils.Cfg.EmailSettings.PushNotificationServer+"/api/v1/send_push", strings.NewReader(msg.ToJson()))
|
||||
|
||||
l4g.Debug("Sending push notification to " + msg.DeviceId + " with msg of '" + msg.Message + "'")
|
||||
l4g.Debug(utils.T("api.post.send_notifications_and_forget.push_notification.debug"), msg.DeviceId, msg.Message)
|
||||
if _, err := httpClient.Do(request); err != nil {
|
||||
l4g.Error("Failed to send push notificationid=%v, err=%v", id, err)
|
||||
l4g.Error(utils.T("api.post.send_notifications_and_forget.push_notification.error"), id, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -695,7 +723,7 @@ func sendNotificationsAndForget(c *Context, post *model.Post, team *model.Team,
|
||||
func updateMentionCountAndForget(channelId, userId string) {
|
||||
go func() {
|
||||
if result := <-Srv.Store.Channel().IncrementMentionCount(channelId, userId); result.Err != nil {
|
||||
l4g.Error("Failed to update mention count for user_id=%v on channel_id=%v err=%v", userId, channelId, result.Err)
|
||||
l4g.Error(utils.T("api.post.update_mention_count_and_forget.update_error"), userId, channelId, result.Err)
|
||||
}
|
||||
}()
|
||||
}
|
||||
@@ -723,19 +751,20 @@ func updatePost(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
oldPost = result.Data.(*model.PostList).Posts[post.Id]
|
||||
|
||||
if oldPost == nil {
|
||||
c.Err = model.NewAppError("updatePost", "We couldn't find the existing post or comment to update.", "id="+post.Id)
|
||||
c.Err = model.NewLocAppError("updatePost", "api.post.update_post.find.app_error", nil, "id="+post.Id)
|
||||
c.Err.StatusCode = http.StatusBadRequest
|
||||
return
|
||||
}
|
||||
|
||||
if oldPost.UserId != c.Session.UserId {
|
||||
c.Err = model.NewAppError("updatePost", "You do not have the appropriate permissions", "oldUserId="+oldPost.UserId)
|
||||
c.Err = model.NewLocAppError("updatePost", "api.post.update_post.permissions.app_error", nil, "oldUserId="+oldPost.UserId)
|
||||
c.Err.StatusCode = http.StatusForbidden
|
||||
return
|
||||
}
|
||||
|
||||
if oldPost.DeleteAt != 0 {
|
||||
c.Err = model.NewAppError("updatePost", "You do not have the appropriate permissions", "Already delted id="+post.Id)
|
||||
c.Err = model.NewLocAppError("updatePost", "api.post.update_post.permissions.app_error", nil,
|
||||
c.T("api.post.update_post.permissions_details.app_error", map[string]interface{}{"PostId": post.Id}))
|
||||
c.Err.StatusCode = http.StatusForbidden
|
||||
return
|
||||
}
|
||||
@@ -870,7 +899,7 @@ func getPost(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
list := result.Data.(*model.PostList)
|
||||
|
||||
if !list.IsChannelId(channelId) {
|
||||
c.Err = model.NewAppError("getPost", "You do not have the appropriate permissions", "")
|
||||
c.Err = model.NewLocAppError("getPost", "api.post.get_post.permissions.app_error", nil, "")
|
||||
c.Err.StatusCode = http.StatusForbidden
|
||||
return
|
||||
}
|
||||
@@ -896,7 +925,7 @@ func getPostById(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
list := result.Data.(*model.PostList)
|
||||
|
||||
if len(list.Order) != 1 {
|
||||
c.Err = model.NewAppError("getPostById", "Unable to get post", "")
|
||||
c.Err = model.NewLocAppError("getPostById", "api.post_get_post_by_id.get.app_error", nil, "")
|
||||
return
|
||||
}
|
||||
post := list.Posts[list.Order[0]]
|
||||
@@ -950,13 +979,13 @@ func deletePost(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
if post.ChannelId != channelId {
|
||||
c.Err = model.NewAppError("deletePost", "You do not have the appropriate permissions", "")
|
||||
c.Err = model.NewLocAppError("deletePost", "api.post.delete_post.permissions.app_error", nil, "")
|
||||
c.Err.StatusCode = http.StatusForbidden
|
||||
return
|
||||
}
|
||||
|
||||
if post.UserId != c.Session.UserId && !c.IsTeamAdmin() {
|
||||
c.Err = model.NewAppError("deletePost", "You do not have the appropriate permissions", "")
|
||||
c.Err = model.NewLocAppError("deletePost", "api.post.delete_post.permissions.app_error", nil, "")
|
||||
c.Err.StatusCode = http.StatusForbidden
|
||||
return
|
||||
}
|
||||
@@ -980,9 +1009,11 @@ func deletePost(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
func getPostsBefore(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
getPostsBeforeOrAfter(c, w, r, true)
|
||||
}
|
||||
|
||||
func getPostsAfter(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
getPostsBeforeOrAfter(c, w, r, false)
|
||||
}
|
||||
|
||||
func getPostsBeforeOrAfter(c *Context, w http.ResponseWriter, r *http.Request, before bool) {
|
||||
params := mux.Vars(r)
|
||||
|
||||
|
||||
@@ -7,11 +7,12 @@ import (
|
||||
l4g "github.com/alecthomas/log4go"
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/mattermost/platform/model"
|
||||
"github.com/mattermost/platform/utils"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
func InitPreference(r *mux.Router) {
|
||||
l4g.Debug("Initializing preference api routes")
|
||||
l4g.Debug(utils.T("api.preference.init.debug"))
|
||||
|
||||
sr := r.PathPrefix("/preferences").Subrouter()
|
||||
sr.Handle("/", ApiUserRequired(getAllPreferences)).Methods("GET")
|
||||
@@ -33,14 +34,16 @@ func getAllPreferences(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
func savePreferences(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
preferences, err := model.PreferencesFromJson(r.Body)
|
||||
if err != nil {
|
||||
c.Err = model.NewAppError("savePreferences", "Unable to decode preferences from request", err.Error())
|
||||
c.Err = model.NewLocAppError("savePreferences", "api.preference.save_preferences.decode.app_error", nil, err.Error())
|
||||
c.Err.StatusCode = http.StatusBadRequest
|
||||
return
|
||||
}
|
||||
|
||||
for _, preference := range preferences {
|
||||
if c.Session.UserId != preference.UserId {
|
||||
c.Err = model.NewAppError("savePreferences", "Unable to set preferences for other user", "session.user_id="+c.Session.UserId+", preference.user_id="+preference.UserId)
|
||||
c.Err = model.NewLocAppError("savePreferences", "api.preference.save_preferences.set.app_error", nil,
|
||||
c.T("api.preference.save_preferences.set_details.app_error",
|
||||
map[string]interface{}{"SessionUserId": c.Session.UserId, "PreferenceUserId": preference.UserId}))
|
||||
c.Err.StatusCode = http.StatusUnauthorized
|
||||
return
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ var Srv *Server
|
||||
|
||||
func NewServer() {
|
||||
|
||||
l4g.Info("Server is initializing...")
|
||||
l4g.Info(utils.T("api.server.new_server.init.info"))
|
||||
|
||||
Srv = &Server{}
|
||||
Srv.Store = store.NewSqlStore()
|
||||
@@ -35,13 +35,13 @@ func NewServer() {
|
||||
}
|
||||
|
||||
func StartServer() {
|
||||
l4g.Info("Starting Server...")
|
||||
l4g.Info("Server is listening on " + utils.Cfg.ServiceSettings.ListenAddress)
|
||||
l4g.Info(utils.T("api.server.start_server.starting.info"))
|
||||
l4g.Info(utils.T("api.server.start_server.listening.info"), utils.Cfg.ServiceSettings.ListenAddress)
|
||||
|
||||
var handler http.Handler = Srv.Router
|
||||
|
||||
if utils.Cfg.RateLimitSettings.EnableRateLimiter {
|
||||
l4g.Info("RateLimiter is enabled")
|
||||
l4g.Info(utils.T("api.server.start_server.rate.info"))
|
||||
|
||||
vary := throttled.VaryBy{}
|
||||
|
||||
@@ -53,7 +53,7 @@ func StartServer() {
|
||||
vary.Headers = strings.Fields(utils.Cfg.RateLimitSettings.VaryByHeader)
|
||||
|
||||
if utils.Cfg.RateLimitSettings.VaryByRemoteAddr {
|
||||
l4g.Warn("RateLimitSettings not configured properly using VaryByHeader and disabling VaryByRemoteAddr")
|
||||
l4g.Warn(utils.T("api.server.start_server.rate.warn"))
|
||||
vary.RemoteAddr = false
|
||||
}
|
||||
}
|
||||
@@ -71,20 +71,20 @@ func StartServer() {
|
||||
go func() {
|
||||
err := manners.ListenAndServe(utils.Cfg.ServiceSettings.ListenAddress, handler)
|
||||
if err != nil {
|
||||
l4g.Critical("Error starting server, err:%v", err)
|
||||
l4g.Critical(utils.T("api.server.start_server.starting.critical"), err)
|
||||
time.Sleep(time.Second)
|
||||
panic("Error starting server " + err.Error())
|
||||
panic(utils.T("api.server.start_server.starting.panic") + err.Error())
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
func StopServer() {
|
||||
|
||||
l4g.Info("Stopping Server...")
|
||||
l4g.Info(utils.T("api.server.stop_server.stopping.info"))
|
||||
|
||||
manners.Close()
|
||||
Srv.Store.Close()
|
||||
hub.Stop()
|
||||
|
||||
l4g.Info("Server stopped")
|
||||
l4g.Info(utils.T("api.server.stop_server.stopped.info"))
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ import (
|
||||
"encoding/json"
|
||||
l4g "github.com/alecthomas/log4go"
|
||||
"github.com/mattermost/platform/model"
|
||||
"github.com/mattermost/platform/utils"
|
||||
"io"
|
||||
"mime/multipart"
|
||||
"strconv"
|
||||
@@ -44,7 +45,7 @@ func SlackConvertTimeStamp(ts string) int64 {
|
||||
|
||||
timeStamp, err := strconv.ParseInt(timeString, 10, 64)
|
||||
if err != nil {
|
||||
l4g.Warn("Bad timestamp detected")
|
||||
l4g.Warn(utils.T("api.slackimport.slack_convert_timestamp.bad.warn"))
|
||||
return 1
|
||||
}
|
||||
return timeStamp * 1000 // Convert to milliseconds
|
||||
@@ -91,7 +92,7 @@ func SlackParsePosts(data io.Reader) []SlackPost {
|
||||
|
||||
func SlackAddUsers(teamId string, slackusers []SlackUser, log *bytes.Buffer) map[string]*model.User {
|
||||
// Log header
|
||||
log.WriteString("\r\n Users Created\r\n")
|
||||
log.WriteString(utils.T("api.slackimport.slack_add_users.created"))
|
||||
log.WriteString("===============\r\n\r\n")
|
||||
|
||||
addedUsers := make(map[string]*model.User)
|
||||
@@ -118,9 +119,9 @@ func SlackAddUsers(teamId string, slackusers []SlackUser, log *bytes.Buffer) map
|
||||
|
||||
if mUser := ImportUser(&newUser); mUser != nil {
|
||||
addedUsers[sUser.Id] = mUser
|
||||
log.WriteString("Email, Password: " + newUser.Email + ", " + password + "\r\n")
|
||||
log.WriteString(utils.T("api.slackimport.slack_add_users.email_pwd", map[string]interface{}{"Email": newUser.Email, "Password": password}))
|
||||
} else {
|
||||
log.WriteString("Unable to import user: " + sUser.Username + "\r\n")
|
||||
log.WriteString(utils.T("api.slackimport.slack_add_users.unable_import", map[string]interface{}{"Username": sUser.Username}))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -132,10 +133,10 @@ func SlackAddPosts(channel *model.Channel, posts []SlackPost, users map[string]*
|
||||
switch {
|
||||
case sPost.Type == "message" && (sPost.SubType == "" || sPost.SubType == "file_share"):
|
||||
if sPost.User == "" {
|
||||
l4g.Debug("Message without user")
|
||||
l4g.Debug(utils.T("api.slackimport.slack_add_posts.without_user.debug"))
|
||||
continue
|
||||
} else if users[sPost.User] == nil {
|
||||
l4g.Debug("User: " + sPost.User + " does not exist!")
|
||||
l4g.Debug(utils.T("api.slackimport.slack_add_posts.user_no_exists.debug"), sPost.User)
|
||||
continue
|
||||
}
|
||||
newPost := model.Post{
|
||||
@@ -147,10 +148,10 @@ func SlackAddPosts(channel *model.Channel, posts []SlackPost, users map[string]*
|
||||
ImportPost(&newPost)
|
||||
case sPost.Type == "message" && sPost.SubType == "file_comment":
|
||||
if sPost.Comment["user"] == "" {
|
||||
l4g.Debug("Message without user")
|
||||
l4g.Debug(utils.T("api.slackimport.slack_add_posts.msg_no_usr.debug"))
|
||||
continue
|
||||
} else if users[sPost.Comment["user"]] == nil {
|
||||
l4g.Debug("User: " + sPost.User + " does not exist!")
|
||||
l4g.Debug(utils.T("api.slackimport.slack_add_posts.user_no_exists.debug"), sPost.User)
|
||||
continue
|
||||
}
|
||||
newPost := model.Post{
|
||||
@@ -163,16 +164,16 @@ func SlackAddPosts(channel *model.Channel, posts []SlackPost, users map[string]*
|
||||
case sPost.Type == "message" && sPost.SubType == "bot_message":
|
||||
// In the future this will use the "Action Post" spec to post
|
||||
// a message without using a username. For now we just warn that we don't handle this case
|
||||
l4g.Warn("Slack bot posts are not imported yet")
|
||||
l4g.Warn(utils.T("api.slackimport.slack_add_posts.bot.warn"))
|
||||
default:
|
||||
l4g.Warn("Unsupported post type: " + sPost.Type + ", " + sPost.SubType)
|
||||
l4g.Warn(utils.T("api.slackimport.slack_add_posts.unsupported.warn"), sPost.Type, sPost.SubType)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func SlackAddChannels(teamId string, slackchannels []SlackChannel, posts map[string][]SlackPost, users map[string]*model.User, log *bytes.Buffer) map[string]*model.Channel {
|
||||
// Write Header
|
||||
log.WriteString("\r\n Channels Added \r\n")
|
||||
log.WriteString(utils.T("api.slackimport.slack_add_channels.added"))
|
||||
log.WriteString("=================\r\n\r\n")
|
||||
|
||||
addedChannels := make(map[string]*model.Channel)
|
||||
@@ -188,12 +189,12 @@ func SlackAddChannels(teamId string, slackchannels []SlackChannel, posts map[str
|
||||
if mChannel == nil {
|
||||
// Maybe it already exists?
|
||||
if result := <-Srv.Store.Channel().GetByName(teamId, sChannel.Name); result.Err != nil {
|
||||
l4g.Debug("Failed to import: %s", newChannel.DisplayName)
|
||||
log.WriteString("Failed to import: " + newChannel.DisplayName + "\r\n")
|
||||
l4g.Debug(utils.T("api.slackimport.slack_add_channels.import_failed.debug"), newChannel.DisplayName)
|
||||
log.WriteString(utils.T("api.slackimport.slack_add_channels.import_failed", map[string]interface{}{"DisplayName": newChannel.DisplayName}))
|
||||
continue
|
||||
} else {
|
||||
mChannel = result.Data.(*model.Channel)
|
||||
log.WriteString("Merged with existing channel: " + newChannel.DisplayName + "\r\n")
|
||||
log.WriteString(utils.T("api.slackimport.slack_add_channels.merge", map[string]interface{}{"DisplayName": newChannel.DisplayName}))
|
||||
}
|
||||
}
|
||||
log.WriteString(newChannel.DisplayName + "\r\n")
|
||||
@@ -207,11 +208,11 @@ func SlackAddChannels(teamId string, slackchannels []SlackChannel, posts map[str
|
||||
func SlackImport(fileData multipart.File, fileSize int64, teamID string) (*model.AppError, *bytes.Buffer) {
|
||||
zipreader, err := zip.NewReader(fileData, fileSize)
|
||||
if err != nil || zipreader.File == nil {
|
||||
return model.NewAppError("SlackImport", "Unable to open zip file", err.Error()), nil
|
||||
return model.NewLocAppError("SlackImport", "api.slackimport.slack_import.zip.app_error", nil, err.Error()), nil
|
||||
}
|
||||
|
||||
// Create log file
|
||||
log := bytes.NewBufferString("Mattermost Slack Import Log\r\n")
|
||||
log := bytes.NewBufferString(utils.T("api.slackimport.slack_import.log"))
|
||||
|
||||
var channels []SlackChannel
|
||||
var users []SlackUser
|
||||
@@ -219,7 +220,7 @@ func SlackImport(fileData multipart.File, fileSize int64, teamID string) (*model
|
||||
for _, file := range zipreader.File {
|
||||
reader, err := file.Open()
|
||||
if err != nil {
|
||||
return model.NewAppError("SlackImport", "Unable to open: "+file.Name, err.Error()), log
|
||||
return model.NewLocAppError("SlackImport", "api.slackimport.slack_import.open.app_error", map[string]interface{}{"Filename": file.Name}, err.Error()), log
|
||||
}
|
||||
if file.Name == "channels.json" {
|
||||
channels = SlackParseChannels(reader)
|
||||
@@ -243,11 +244,11 @@ func SlackImport(fileData multipart.File, fileSize int64, teamID string) (*model
|
||||
addedUsers := SlackAddUsers(teamID, users, log)
|
||||
SlackAddChannels(teamID, channels, posts, addedUsers, log)
|
||||
|
||||
log.WriteString("\r\n Notes \r\n")
|
||||
log.WriteString(utils.T("api.slackimport.slack_import.notes"))
|
||||
log.WriteString("=======\r\n\r\n")
|
||||
|
||||
log.WriteString("- Some posts may not have been imported because they where not supported by this importer.\r\n")
|
||||
log.WriteString("- Slack bot posts are currently not supported.\r\n")
|
||||
log.WriteString(utils.T("api.slackimport.slack_import.note1"))
|
||||
log.WriteString(utils.T("api.slackimport.slack_import.note2"))
|
||||
|
||||
return nil, log
|
||||
}
|
||||
|
||||
54
api/team.go
54
api/team.go
@@ -19,7 +19,7 @@ import (
|
||||
)
|
||||
|
||||
func InitTeam(r *mux.Router) {
|
||||
l4g.Debug("Initializing team api routes")
|
||||
l4g.Debug(utils.T("api.team.init.debug"))
|
||||
|
||||
sr := r.PathPrefix("/teams").Subrouter()
|
||||
sr.Handle("/create", ApiAppHandler(createTeam)).Methods("POST")
|
||||
@@ -40,7 +40,7 @@ func InitTeam(r *mux.Router) {
|
||||
|
||||
func signupTeam(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
if !utils.Cfg.EmailSettings.EnableSignUpWithEmail {
|
||||
c.Err = model.NewAppError("signupTeam", "Team sign-up with email is disabled.", "")
|
||||
c.Err = model.NewLocAppError("signupTeam", "api.team.signup_team.email_disabled.app_error", nil, "")
|
||||
c.Err.StatusCode = http.StatusNotImplemented
|
||||
return
|
||||
}
|
||||
@@ -147,7 +147,7 @@ func createTeamFromSSO(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
func createTeamFromSignup(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
if !utils.Cfg.EmailSettings.EnableSignUpWithEmail {
|
||||
c.Err = model.NewAppError("createTeamFromSignup", "Team sign-up with email is disabled.", "")
|
||||
c.Err = model.NewLocAppError("createTeamFromSignup", "api.team.create_team_from_signup.email_disabled.app_error", nil, "")
|
||||
c.Err.StatusCode = http.StatusNotImplemented
|
||||
return
|
||||
}
|
||||
@@ -188,13 +188,13 @@ func createTeamFromSignup(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
teamSignup.User.Password = password
|
||||
|
||||
if !model.ComparePassword(teamSignup.Hash, fmt.Sprintf("%v:%v", teamSignup.Data, utils.Cfg.EmailSettings.InviteSalt)) {
|
||||
c.Err = model.NewAppError("createTeamFromSignup", "The signup link does not appear to be valid", "")
|
||||
c.Err = model.NewLocAppError("createTeamFromSignup", "api.team.create_team_from_signup.invalid_link.app_error", nil, "")
|
||||
return
|
||||
}
|
||||
|
||||
t, err := strconv.ParseInt(props["time"], 10, 64)
|
||||
if err != nil || model.GetMillis()-t > 1000*60*60 { // one hour
|
||||
c.Err = model.NewAppError("createTeamFromSignup", "The signup link has expired", "")
|
||||
c.Err = model.NewLocAppError("createTeamFromSignup", "api.team.create_team_from_signup.expired_link.app_error", nil, "")
|
||||
return
|
||||
}
|
||||
|
||||
@@ -204,7 +204,7 @@ func createTeamFromSignup(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
if found {
|
||||
c.Err = model.NewAppError("createTeamFromSignup", "This URL is unavailable. Please try another.", "d="+teamSignup.Team.Name)
|
||||
c.Err = model.NewLocAppError("createTeamFromSignup", "api.team.create_team_from_signup.unavailable.app_error", nil, "d="+teamSignup.Team.Name)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -249,7 +249,7 @@ func createTeam(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
func CreateTeam(c *Context, team *model.Team) *model.Team {
|
||||
if !utils.Cfg.EmailSettings.EnableSignUpWithEmail {
|
||||
c.Err = model.NewAppError("createTeam", "Team sign-up with email is disabled.", "")
|
||||
c.Err = model.NewLocAppError("createTeam", "api.team.create_team.email_disabled.app_error", nil, "")
|
||||
c.Err.StatusCode = http.StatusForbidden
|
||||
return nil
|
||||
}
|
||||
@@ -283,7 +283,7 @@ func isTeamCreationAllowed(c *Context, email string) bool {
|
||||
email = strings.ToLower(email)
|
||||
|
||||
if !utils.Cfg.TeamSettings.EnableTeamCreation {
|
||||
c.Err = model.NewAppError("isTeamCreationAllowed", "Team creation has been disabled. Please ask your systems administrator for details.", "")
|
||||
c.Err = model.NewLocAppError("isTeamCreationAllowed", "api.team.is_team_creation_allowed.disabled.app_error", nil, "")
|
||||
return false
|
||||
}
|
||||
|
||||
@@ -300,7 +300,7 @@ func isTeamCreationAllowed(c *Context, email string) bool {
|
||||
}
|
||||
|
||||
if len(utils.Cfg.TeamSettings.RestrictCreationToDomains) > 0 && !matched {
|
||||
c.Err = model.NewAppError("isTeamCreationAllowed", "Email must be from a specific domain (e.g. @example.com). Please ask your systems administrator for details.", "")
|
||||
c.Err = model.NewLocAppError("isTeamCreationAllowed", "api.team.is_team_creation_allowed.domain.app_error", nil, "")
|
||||
return false
|
||||
}
|
||||
|
||||
@@ -445,7 +445,7 @@ func emailTeams(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
bodyPage.Props = props
|
||||
|
||||
if err := utils.SendMail(email, subjectPage.Render(), bodyPage.Render()); err != nil {
|
||||
l4g.Error("An error occured while sending an email in emailTeams err=%v", err)
|
||||
l4g.Error(utils.T("api.team.email_teams.sending.error"), err)
|
||||
}
|
||||
|
||||
w.Write([]byte(model.MapToJson(m)))
|
||||
@@ -455,7 +455,7 @@ func emailTeams(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
func inviteMembers(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
invites := model.InvitesFromJson(r.Body)
|
||||
if len(invites.Invites) == 0 {
|
||||
c.Err = model.NewAppError("Team.InviteMembers", "No one to invite.", "")
|
||||
c.Err = model.NewLocAppError("Team.InviteMembers", "api.team.invite_members.no_one.app_error", nil, "")
|
||||
c.Err.StatusCode = http.StatusBadRequest
|
||||
return
|
||||
}
|
||||
@@ -483,7 +483,7 @@ func inviteMembers(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
for i, invite := range invites.Invites {
|
||||
if result := <-Srv.Store.User().GetByEmail(c.Session.TeamId, invite["email"]); result.Err == nil || result.Err.Message != store.MISSING_ACCOUNT_ERROR {
|
||||
invNum = int64(i)
|
||||
c.Err = model.NewAppError("invite_members", "This person is already on your team", strconv.FormatInt(invNum, 10))
|
||||
c.Err = model.NewLocAppError("invite_members", "api.team.invite_members.already.app_error", nil, strconv.FormatInt(invNum, 10))
|
||||
return
|
||||
}
|
||||
}
|
||||
@@ -506,9 +506,9 @@ func InviteMembers(c *Context, team *model.Team, user *model.User, invites []str
|
||||
|
||||
senderRole := ""
|
||||
if c.IsTeamAdmin() {
|
||||
senderRole = "administrator"
|
||||
senderRole = c.T("api.team.invite_members.admin")
|
||||
} else {
|
||||
senderRole = "member"
|
||||
senderRole = c.T("api.team.invite_members.member")
|
||||
}
|
||||
|
||||
subjectPage := NewServerTemplatePage("invite_subject")
|
||||
@@ -532,11 +532,11 @@ func InviteMembers(c *Context, team *model.Team, user *model.User, invites []str
|
||||
bodyPage.Props["Link"] = fmt.Sprintf("%s/signup_user_complete/?d=%s&h=%s", c.GetSiteURL(), url.QueryEscape(data), url.QueryEscape(hash))
|
||||
|
||||
if !utils.Cfg.EmailSettings.SendEmailNotifications {
|
||||
l4g.Info("sending invitation to %v %v", invite, bodyPage.Props["Link"])
|
||||
l4g.Info(utils.T("api.team.invite_members.sending.info"), invite, bodyPage.Props["Link"])
|
||||
}
|
||||
|
||||
if err := utils.SendMail(invite, subjectPage.Render(), bodyPage.Render()); err != nil {
|
||||
l4g.Error("Failed to send invite email successfully err=%v", err)
|
||||
l4g.Error(utils.T("api.team.invite_members.send.error"), err)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -554,7 +554,7 @@ func updateTeam(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
team.Id = c.Session.TeamId
|
||||
|
||||
if !c.IsTeamAdmin() {
|
||||
c.Err = model.NewAppError("updateTeam", "You do not have the appropriate permissions", "userId="+c.Session.UserId)
|
||||
c.Err = model.NewLocAppError("updateTeam", "api.team.update_team.permissions.app_error", nil, "userId="+c.Session.UserId)
|
||||
c.Err.StatusCode = http.StatusForbidden
|
||||
return
|
||||
}
|
||||
@@ -586,7 +586,7 @@ func updateTeam(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
func PermanentDeleteTeam(c *Context, team *model.Team) *model.AppError {
|
||||
l4g.Warn("Attempting to permanently delete team %v id=%v", team.Name, team.Id)
|
||||
l4g.Warn(utils.T("api.team.permanent_delete_team.attempting.warn"), team.Name, team.Id)
|
||||
c.Path = "/teams/permanent_delete"
|
||||
c.LogAuditWithUserId("", fmt.Sprintf("attempt teamId=%v", team.Id))
|
||||
|
||||
@@ -612,7 +612,7 @@ func PermanentDeleteTeam(c *Context, team *model.Team) *model.AppError {
|
||||
return result.Err
|
||||
}
|
||||
|
||||
l4g.Warn("Permanently deleted team %v id=%v", team.Name, team.Id)
|
||||
l4g.Warn(utils.T("api.team.permanent_delete_team.deleted.warn"), team.Name, team.Id)
|
||||
c.LogAuditWithUserId("", fmt.Sprintf("success teamId=%v", team.Id))
|
||||
|
||||
return nil
|
||||
@@ -639,13 +639,13 @@ func getMyTeam(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
func importTeam(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
if !c.HasPermissionsToTeam(c.Session.TeamId, "import") || !c.IsTeamAdmin() {
|
||||
c.Err = model.NewAppError("importTeam", "Only a team admin can import data.", "userId="+c.Session.UserId)
|
||||
c.Err = model.NewLocAppError("importTeam", "api.team.import_team.admin.app_error", nil, "userId="+c.Session.UserId)
|
||||
c.Err.StatusCode = http.StatusForbidden
|
||||
return
|
||||
}
|
||||
|
||||
if err := r.ParseMultipartForm(10000000); err != nil {
|
||||
c.Err = model.NewAppError("importTeam", "Could not parse multipart form", err.Error())
|
||||
c.Err = model.NewLocAppError("importTeam", "api.team.import_team.parse.app_error", nil, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
@@ -654,27 +654,27 @@ func importTeam(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
fileSizeStr, ok := r.MultipartForm.Value["filesize"]
|
||||
if !ok {
|
||||
c.Err = model.NewAppError("importTeam", "Filesize unavilable", "")
|
||||
c.Err = model.NewLocAppError("importTeam", "api.team.import_team.unavailable.app_error", nil, "")
|
||||
c.Err.StatusCode = http.StatusBadRequest
|
||||
return
|
||||
}
|
||||
|
||||
fileSize, err := strconv.ParseInt(fileSizeStr[0], 10, 64)
|
||||
if err != nil {
|
||||
c.Err = model.NewAppError("importTeam", "Filesize not an integer", "")
|
||||
c.Err = model.NewLocAppError("importTeam", "api.team.import_team.integer.app_error", nil, "")
|
||||
c.Err.StatusCode = http.StatusBadRequest
|
||||
return
|
||||
}
|
||||
|
||||
fileInfoArray, ok := r.MultipartForm.File["file"]
|
||||
if !ok {
|
||||
c.Err = model.NewAppError("importTeam", "No file under 'file' in request", "")
|
||||
c.Err = model.NewLocAppError("importTeam", "api.team.import_team.no_file.app_error", nil, "")
|
||||
c.Err.StatusCode = http.StatusBadRequest
|
||||
return
|
||||
}
|
||||
|
||||
if len(fileInfoArray) <= 0 {
|
||||
c.Err = model.NewAppError("importTeam", "Empty array under 'file' in request", "")
|
||||
c.Err = model.NewLocAppError("importTeam", "api.team.import_team.array.app_error", nil, "")
|
||||
c.Err.StatusCode = http.StatusBadRequest
|
||||
return
|
||||
}
|
||||
@@ -684,7 +684,7 @@ func importTeam(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
fileData, err := fileInfo.Open()
|
||||
defer fileData.Close()
|
||||
if err != nil {
|
||||
c.Err = model.NewAppError("importTeam", "Could not open file", err.Error())
|
||||
c.Err = model.NewLocAppError("importTeam", "api.team.import_team.open.app_error", nil, err.Error())
|
||||
c.Err.StatusCode = http.StatusBadRequest
|
||||
return
|
||||
}
|
||||
@@ -706,7 +706,7 @@ func importTeam(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
func exportTeam(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
if !c.HasPermissionsToTeam(c.Session.TeamId, "export") || !c.IsTeamAdmin() {
|
||||
c.Err = model.NewAppError("exportTeam", "Only a team admin can export data.", "userId="+c.Session.UserId)
|
||||
c.Err = model.NewLocAppError("exportTeam", "api.team.export_team.admin.app_error", nil, "userId="+c.Session.UserId)
|
||||
c.Err.StatusCode = http.StatusForbidden
|
||||
return
|
||||
}
|
||||
|
||||
@@ -11,8 +11,8 @@
|
||||
<script src="/static/js/bootstrap-3.3.5.min.js"></script>
|
||||
<script src="/static/js/react-bootstrap-0.25.1.min.js"></script>
|
||||
|
||||
<link id="favicon" rel="icon" href="/static/images/favicon.ico" type="image/x-icon">
|
||||
<link rel="shortcut icon" href="/static/images/favicon.ico" type="image/x-icon">
|
||||
<link id="favicon" rel="icon" href="/static/images/favicon/favicon-16x16.png" type="image/x-icon">
|
||||
<link rel="shortcut icon" href="/static/images/favicon/favicon-16x16.png" type="image/x-icon">
|
||||
<link href='/static/css/google-fonts.css' rel='stylesheet' type='text/css'>
|
||||
<link rel="stylesheet" href="/static/css/styles.css">
|
||||
|
||||
|
||||
@@ -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 updated your password</h2>
|
||||
<p>You updated your password for {{.Props.TeamDisplayName}} on {{ .Props.TeamURL }} by {{.Props.Method}}.<br>If this change wasn't initiated by you, please contact your system administrator.</p>
|
||||
<p>Your password has been updated for {{.Props.TeamDisplayName}} on {{ .Props.TeamURL }} by {{.Props.Method}}.<br>If this change wasn't initiated by you, please contact your system administrator.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
|
||||
@@ -1 +1 @@
|
||||
{{define "password_change_subject"}}You updated your password for {{.Props.TeamDisplayName}} on {{ .ClientCfg.SiteName }}{{end}}
|
||||
{{define "password_change_subject"}}Your password has been updated for {{.Props.TeamDisplayName}} on {{ .ClientCfg.SiteName }}{{end}}
|
||||
|
||||
180
api/user.go
180
api/user.go
@@ -32,7 +32,7 @@ import (
|
||||
)
|
||||
|
||||
func InitUser(r *mux.Router) {
|
||||
l4g.Debug("Initializing user api routes")
|
||||
l4g.Debug(utils.T("api.user.init.debug"))
|
||||
|
||||
sr := r.PathPrefix("/users").Subrouter()
|
||||
sr.Handle("/create", ApiAppHandler(createUser)).Methods("POST")
|
||||
@@ -64,7 +64,7 @@ func InitUser(r *mux.Router) {
|
||||
|
||||
func createUser(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
if !utils.Cfg.EmailSettings.EnableSignUpWithEmail || !utils.Cfg.TeamSettings.EnableUserCreation {
|
||||
c.Err = model.NewAppError("signupTeam", "User sign-up with email is disabled.", "")
|
||||
c.Err = model.NewLocAppError("signupTeam", "api.user.create_user.signup_email_disabled.app_error", nil, "")
|
||||
c.Err.StatusCode = http.StatusNotImplemented
|
||||
return
|
||||
}
|
||||
@@ -98,18 +98,18 @@ func createUser(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
props := model.MapFromJson(strings.NewReader(data))
|
||||
|
||||
if !model.ComparePassword(hash, fmt.Sprintf("%v:%v", data, utils.Cfg.EmailSettings.InviteSalt)) {
|
||||
c.Err = model.NewAppError("createUser", "The signup link does not appear to be valid", "")
|
||||
c.Err = model.NewLocAppError("createUser", "api.user.create_user.signup_link_invalid.app_error", nil, "")
|
||||
return
|
||||
}
|
||||
|
||||
t, err := strconv.ParseInt(props["time"], 10, 64)
|
||||
if err != nil || model.GetMillis()-t > 1000*60*60*48 { // 48 hours
|
||||
c.Err = model.NewAppError("createUser", "The signup link has expired", "")
|
||||
c.Err = model.NewLocAppError("createUser", "api.user.create_user.signup_link_expired.app_error", nil, "")
|
||||
return
|
||||
}
|
||||
|
||||
if user.TeamId != props["id"] {
|
||||
c.Err = model.NewAppError("createUser", "Invalid team name", data)
|
||||
c.Err = model.NewLocAppError("createUser", "api.user.create_user.team_name.app_error", nil, data)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -123,7 +123,7 @@ func createUser(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
if !CheckUserDomain(user, utils.Cfg.TeamSettings.RestrictCreationToDomains) {
|
||||
c.Err = model.NewAppError("createUser", "The email you provided does not belong to an accepted domain. Please contact your administrator or sign up with a different email.", "")
|
||||
c.Err = model.NewLocAppError("createUser", "api.user.create_user.accepted_domain.app_error", nil, "")
|
||||
return
|
||||
}
|
||||
|
||||
@@ -208,27 +208,27 @@ func CreateUser(team *model.Team, user *model.User) (*model.User, *model.AppErro
|
||||
user.MakeNonNil()
|
||||
|
||||
if result := <-Srv.Store.User().Save(user); result.Err != nil {
|
||||
l4g.Error("Couldn't save the user err=%v", result.Err)
|
||||
l4g.Error(utils.T("api.user.create_user.save.error"), result.Err)
|
||||
return nil, result.Err
|
||||
} else {
|
||||
ruser := result.Data.(*model.User)
|
||||
|
||||
// Soft error if there is an issue joining the default channels
|
||||
if err := JoinDefaultChannels(ruser, channelRole); err != nil {
|
||||
l4g.Error("Encountered an issue joining default channels user_id=%s, team_id=%s, err=%v", ruser.Id, ruser.TeamId, err)
|
||||
l4g.Error(utils.T("api.user.create_user.joining.error"), ruser.Id, ruser.TeamId, err)
|
||||
}
|
||||
|
||||
addDirectChannelsAndForget(ruser)
|
||||
|
||||
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)
|
||||
l4g.Error(utils.T("api.user.create_user.verified.error"), cresult.Err)
|
||||
}
|
||||
}
|
||||
|
||||
pref := model.Preference{UserId: ruser.Id, Category: model.PREFERENCE_CATEGORY_TUTORIAL_STEPS, Name: ruser.Id, Value: "0"}
|
||||
if presult := <-Srv.Store.Preference().Save(&model.Preferences{pref}); presult.Err != nil {
|
||||
l4g.Error("Encountered error saving tutorial preference, err=%v", presult.Err.Message)
|
||||
l4g.Error(utils.T("api.user.create_user.tutorial.error"), presult.Err.Message)
|
||||
}
|
||||
|
||||
ruser.Sanitize(map[string]bool{})
|
||||
@@ -246,14 +246,14 @@ func CreateOAuthUser(c *Context, w http.ResponseWriter, r *http.Request, service
|
||||
var user *model.User
|
||||
provider := einterfaces.GetOauthProvider(service)
|
||||
if provider == nil {
|
||||
c.Err = model.NewAppError("CreateOAuthUser", service+" oauth not avlailable on this server", "")
|
||||
c.Err = model.NewLocAppError("CreateOAuthUser", "api.user.create_oauth_user.not_available.app_error", map[string]interface{}{"Service": service}, "")
|
||||
return nil
|
||||
} else {
|
||||
user = provider.GetUserFromJson(userData)
|
||||
}
|
||||
|
||||
if user == nil {
|
||||
c.Err = model.NewAppError("CreateOAuthUser", "Could not create user out of "+service+" user object", "")
|
||||
c.Err = model.NewLocAppError("CreateOAuthUser", "api.user.create_oauth_user.create.app_error", map[string]interface{}{"Service": service}, "")
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -280,12 +280,14 @@ func CreateOAuthUser(c *Context, w http.ResponseWriter, r *http.Request, service
|
||||
}
|
||||
|
||||
if result := <-suchan; result.Err == nil {
|
||||
c.Err = model.NewAppError("signupCompleteOAuth", "This "+service+" account has already been used to sign up for team "+team.DisplayName, "email="+user.Email)
|
||||
c.Err = model.NewLocAppError("signupCompleteOAuth", "api.user.create_oauth_user.already_used.app_error",
|
||||
map[string]interface{}{"Service": service, "DisplayName": team.DisplayName}, "email="+user.Email)
|
||||
return nil
|
||||
}
|
||||
|
||||
if result := <-euchan; result.Err == nil {
|
||||
c.Err = model.NewAppError("signupCompleteOAuth", "Team "+team.DisplayName+" already has a user with the email address attached to your "+service+" account", "email="+user.Email)
|
||||
c.Err = model.NewLocAppError("signupCompleteOAuth", "api.user.create_oauth_user.already_attached.app_error",
|
||||
map[string]interface{}{"Service": service, "DisplayName": team.DisplayName}, "email="+user.Email)
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -321,7 +323,7 @@ func sendWelcomeEmailAndForget(userId, email, teamName, teamDisplayName, siteURL
|
||||
}
|
||||
|
||||
if err := utils.SendMail(email, subjectPage.Render(), bodyPage.Render()); err != nil {
|
||||
l4g.Error("Failed to send welcome email successfully err=%v", err)
|
||||
l4g.Error(utils.T("api.user.send_welcome_email_and_forget.failed.error"), err)
|
||||
}
|
||||
}()
|
||||
}
|
||||
@@ -330,7 +332,7 @@ func addDirectChannelsAndForget(user *model.User) {
|
||||
go func() {
|
||||
var profiles map[string]*model.User
|
||||
if result := <-Srv.Store.User().GetProfiles(user.TeamId); result.Err != nil {
|
||||
l4g.Error("Failed to add direct channel preferences for user user_id=%s, team_id=%s, err=%v", user.Id, user.TeamId, result.Err.Error())
|
||||
l4g.Error(utils.T("api.user.add_direct_channels_and_forget.failed.error"), user.Id, user.TeamId, result.Err.Error())
|
||||
return
|
||||
} else {
|
||||
profiles = result.Data.(map[string]*model.User)
|
||||
@@ -360,7 +362,7 @@ func addDirectChannelsAndForget(user *model.User) {
|
||||
}
|
||||
|
||||
if result := <-Srv.Store.Preference().Save(&preferences); result.Err != nil {
|
||||
l4g.Error("Failed to add direct channel preferences for new user user_id=%s, eam_id=%s, err=%v", user.Id, user.TeamId, result.Err.Error())
|
||||
l4g.Error(utils.T("api.user.add_direct_channels_and_forget.failed.error"), user.Id, user.TeamId, result.Err.Error())
|
||||
}
|
||||
}()
|
||||
}
|
||||
@@ -379,7 +381,7 @@ func SendVerifyEmailAndForget(userId, userEmail, teamName, teamDisplayName, site
|
||||
bodyPage.Props["VerifyUrl"] = link
|
||||
|
||||
if err := utils.SendMail(userEmail, subjectPage.Render(), bodyPage.Render()); err != nil {
|
||||
l4g.Error("Failed to send verification email successfully err=%v", err)
|
||||
l4g.Error(utils.T("api.user.send_verify_email_and_forget.failed.error"), err)
|
||||
}
|
||||
}()
|
||||
}
|
||||
@@ -417,7 +419,8 @@ func LoginByEmail(c *Context, w http.ResponseWriter, r *http.Request, email, nam
|
||||
user := result.Data.(*model.User)
|
||||
|
||||
if len(user.AuthData) != 0 {
|
||||
c.Err = model.NewAppError("LoginByEmail", "Please sign in using "+user.AuthService, "")
|
||||
c.Err = model.NewLocAppError("LoginByEmail", "api.user.login_by_email.sign_in.app_error",
|
||||
map[string]interface{}{"AuthService": user.AuthService}, "")
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -434,14 +437,16 @@ func LoginByOAuth(c *Context, w http.ResponseWriter, r *http.Request, service st
|
||||
authData := ""
|
||||
provider := einterfaces.GetOauthProvider(service)
|
||||
if provider == nil {
|
||||
c.Err = model.NewAppError("LoginByOAuth", service+" oauth not avlailable on this server", "")
|
||||
c.Err = model.NewLocAppError("LoginByOAuth", "api.user.login_by_oauth.not_available.app_error",
|
||||
map[string]interface{}{"Service": service}, "")
|
||||
return nil
|
||||
} else {
|
||||
authData = provider.GetAuthDataFromJson(userData)
|
||||
}
|
||||
|
||||
if len(authData) == 0 {
|
||||
c.Err = model.NewAppError("LoginByOAuth", "Could not parse auth data out of "+service+" user object", "")
|
||||
c.Err = model.NewLocAppError("LoginByOAuth", "api.user.login_by_oauth.parse.app_error",
|
||||
map[string]interface{}{"Service": service}, "")
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -459,7 +464,7 @@ func LoginByOAuth(c *Context, w http.ResponseWriter, r *http.Request, service st
|
||||
func checkUserLoginAttempts(c *Context, user *model.User) bool {
|
||||
if user.FailedAttempts >= utils.Cfg.ServiceSettings.MaximumLoginAttempts {
|
||||
c.LogAuditWithUserId(user.Id, "fail")
|
||||
c.Err = model.NewAppError("checkUserLoginAttempts", "Your account is locked because of too many failed password attempts. Please reset your password.", "user_id="+user.Id)
|
||||
c.Err = model.NewLocAppError("checkUserLoginAttempts", "api.user.check_user_login_attempts.too_many.app_error", nil, "user_id="+user.Id)
|
||||
c.Err.StatusCode = http.StatusForbidden
|
||||
return false
|
||||
}
|
||||
@@ -471,7 +476,7 @@ func checkUserPassword(c *Context, user *model.User, password string) bool {
|
||||
|
||||
if !model.ComparePassword(user.Password, password) {
|
||||
c.LogAuditWithUserId(user.Id, "fail")
|
||||
c.Err = model.NewAppError("checkUserPassword", "Login failed because of invalid password", "user_id="+user.Id)
|
||||
c.Err = model.NewLocAppError("checkUserPassword", "api.user.check_user_password.invalid.app_error", nil, "user_id="+user.Id)
|
||||
c.Err.StatusCode = http.StatusForbidden
|
||||
|
||||
if result := <-Srv.Store.User().UpdateFailedPasswordAttempts(user.Id, user.FailedAttempts+1); result.Err != nil {
|
||||
@@ -494,13 +499,13 @@ func Login(c *Context, w http.ResponseWriter, r *http.Request, user *model.User,
|
||||
c.LogAuditWithUserId(user.Id, "attempt")
|
||||
|
||||
if !user.EmailVerified && utils.Cfg.EmailSettings.RequireEmailVerification {
|
||||
c.Err = model.NewAppError("Login", "Login failed because email address has not been verified", "user_id="+user.Id)
|
||||
c.Err = model.NewLocAppError("Login", "api.user.login.not_verified.app_error", nil, "user_id="+user.Id)
|
||||
c.Err.StatusCode = http.StatusForbidden
|
||||
return
|
||||
}
|
||||
|
||||
if user.DeleteAt > 0 {
|
||||
c.Err = model.NewAppError("Login", "Login failed because your account has been set to inactive. Please contact an administrator.", "user_id="+user.Id)
|
||||
c.Err = model.NewLocAppError("Login", "api.user.login.inactive.app_error", nil, "user_id="+user.Id)
|
||||
c.Err.StatusCode = http.StatusForbidden
|
||||
return
|
||||
}
|
||||
@@ -522,7 +527,7 @@ func Login(c *Context, w http.ResponseWriter, r *http.Request, user *model.User,
|
||||
sessions := result.Data.([]*model.Session)
|
||||
for _, session := range sessions {
|
||||
if session.DeviceId == deviceId {
|
||||
l4g.Debug("Revoking sessionId=" + session.Id + " for userId=" + user.Id + " re-login with same device Id")
|
||||
l4g.Debug(utils.T("api.user.login.revoking.app_error"), session.Id, user.Id)
|
||||
RevokeSessionById(c, session.Id)
|
||||
if c.Err != nil {
|
||||
c.LogError(c.Err)
|
||||
@@ -604,7 +609,7 @@ func login(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
props := model.MapFromJson(r.Body)
|
||||
|
||||
if len(props["password"]) == 0 {
|
||||
c.Err = model.NewAppError("login", "Password field must not be blank", "")
|
||||
c.Err = model.NewLocAppError("login", "api.user.login.blank_pwd.app_error", nil, "")
|
||||
c.Err.StatusCode = http.StatusForbidden
|
||||
return
|
||||
}
|
||||
@@ -615,7 +620,7 @@ func login(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
} else if len(props["email"]) != 0 && len(props["name"]) != 0 {
|
||||
user = LoginByEmail(c, w, r, props["email"], props["name"], props["password"], props["device_id"])
|
||||
} else {
|
||||
c.Err = model.NewAppError("login", "Either user id or team name and user email must be provided", "")
|
||||
c.Err = model.NewLocAppError("login", "api.user.login.not_provided.app_error", nil, "")
|
||||
c.Err.StatusCode = http.StatusForbidden
|
||||
return
|
||||
}
|
||||
@@ -634,7 +639,7 @@ func login(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
func loginLdap(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
if !*utils.Cfg.LdapSettings.Enable {
|
||||
c.Err = model.NewAppError("loginLdap", "LDAP not enabled on this server", "")
|
||||
c.Err = model.NewLocAppError("loginLdap", "api.user.login_ldap.disabled.app_error", nil, "")
|
||||
c.Err.StatusCode = http.StatusNotImplemented
|
||||
return
|
||||
}
|
||||
@@ -646,13 +651,13 @@ func loginLdap(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
teamName := props["teamName"]
|
||||
|
||||
if len(password) == 0 {
|
||||
c.Err = model.NewAppError("loginLdap", "Password field must not be blank", "")
|
||||
c.Err = model.NewLocAppError("loginLdap", "api.user.login_ldap.blank_pwd.app_error", nil, "")
|
||||
c.Err.StatusCode = http.StatusForbidden
|
||||
return
|
||||
}
|
||||
|
||||
if len(id) == 0 {
|
||||
c.Err = model.NewAppError("loginLdap", "Need an ID", "")
|
||||
c.Err = model.NewLocAppError("loginLdap", "api.user.login_ldap.need_id.app_error", nil, "")
|
||||
c.Err.StatusCode = http.StatusForbidden
|
||||
return
|
||||
}
|
||||
@@ -661,7 +666,7 @@ func loginLdap(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
ldapInterface := einterfaces.GetLdapInterface()
|
||||
if ldapInterface == nil {
|
||||
c.Err = model.NewAppError("loginLdap", "LDAP not available on this server", "")
|
||||
c.Err = model.NewLocAppError("loginLdap", "api.user.login_ldap.not_available.app_error", nil, "")
|
||||
c.Err.StatusCode = http.StatusNotImplemented
|
||||
return
|
||||
}
|
||||
@@ -794,7 +799,7 @@ func getMe(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
if result := <-Srv.Store.User().Get(c.Session.UserId); result.Err != nil {
|
||||
c.Err = result.Err
|
||||
c.RemoveSessionCookie(w, r)
|
||||
l4g.Error("Error in getting users profile for id=%v forcing logout", c.Session.UserId)
|
||||
l4g.Error(utils.T("api.user.get_me.getting.error"), c.Session.UserId)
|
||||
return
|
||||
} else if HandleEtag(result.Data.(*model.User).Etag(), w, r) {
|
||||
return
|
||||
@@ -947,11 +952,11 @@ func createProfileImage(username string, userId string) ([]byte, *model.AppError
|
||||
|
||||
fontBytes, err := ioutil.ReadFile(utils.FindDir("web/static/fonts") + utils.Cfg.FileSettings.InitialFont)
|
||||
if err != nil {
|
||||
return nil, model.NewAppError("createProfileImage", "Could not create default profile image font", err.Error())
|
||||
return nil, model.NewLocAppError("createProfileImage", "api.user.create_profile_image.default_font.app_error", nil, err.Error())
|
||||
}
|
||||
font, err := freetype.ParseFont(fontBytes)
|
||||
if err != nil {
|
||||
return nil, model.NewAppError("createProfileImage", "Could not create default profile image font", err.Error())
|
||||
return nil, model.NewLocAppError("createProfileImage", "api.user.create_profile_image.default_font.app_error", nil, err.Error())
|
||||
}
|
||||
|
||||
width := int(utils.Cfg.FileSettings.ProfileWidth)
|
||||
@@ -972,13 +977,13 @@ func createProfileImage(username string, userId string) ([]byte, *model.AppError
|
||||
pt := freetype.Pt(width/6, height*2/3)
|
||||
_, err = c.DrawString(initial, pt)
|
||||
if err != nil {
|
||||
return nil, model.NewAppError("createProfileImage", "Could not add user initial to default profile picture", err.Error())
|
||||
return nil, model.NewLocAppError("createProfileImage", "api.user.create_profile_image.initial.app_error", nil, err.Error())
|
||||
}
|
||||
|
||||
buf := new(bytes.Buffer)
|
||||
|
||||
if imgErr := png.Encode(buf, dstImg); imgErr != nil {
|
||||
return nil, model.NewAppError("createProfileImage", "Could not encode default profile image", imgErr.Error())
|
||||
return nil, model.NewLocAppError("createProfileImage", "api.user.create_profile_image.encode.app_error", nil, imgErr.Error())
|
||||
} else {
|
||||
return buf.Bytes(), nil
|
||||
}
|
||||
@@ -1033,13 +1038,13 @@ func getProfileImage(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
func uploadProfileImage(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
if len(utils.Cfg.FileSettings.DriverName) == 0 {
|
||||
c.Err = model.NewAppError("uploadProfileImage", "Unable to upload file. Image storage is not configured.", "")
|
||||
c.Err = model.NewLocAppError("uploadProfileImage", "api.user.upload_profile_user.storage.app_error", nil, "")
|
||||
c.Err.StatusCode = http.StatusNotImplemented
|
||||
return
|
||||
}
|
||||
|
||||
if err := r.ParseMultipartForm(10000000); err != nil {
|
||||
c.Err = model.NewAppError("uploadProfileImage", "Could not parse multipart form", "")
|
||||
c.Err = model.NewLocAppError("uploadProfileImage", "api.user.upload_profile_user.parse.app_error", nil, "")
|
||||
return
|
||||
}
|
||||
|
||||
@@ -1047,13 +1052,13 @@ func uploadProfileImage(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
imageArray, ok := m.File["image"]
|
||||
if !ok {
|
||||
c.Err = model.NewAppError("uploadProfileImage", "No file under 'image' in request", "")
|
||||
c.Err = model.NewLocAppError("uploadProfileImage", "api.user.upload_profile_user.no_file.app_error", nil, "")
|
||||
c.Err.StatusCode = http.StatusBadRequest
|
||||
return
|
||||
}
|
||||
|
||||
if len(imageArray) <= 0 {
|
||||
c.Err = model.NewAppError("uploadProfileImage", "Empty array under 'image' in request", "")
|
||||
c.Err = model.NewLocAppError("uploadProfileImage", "api.user.upload_profile_user.array.app_error", nil, "")
|
||||
c.Err.StatusCode = http.StatusBadRequest
|
||||
return
|
||||
}
|
||||
@@ -1063,17 +1068,17 @@ func uploadProfileImage(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
file, err := imageData.Open()
|
||||
defer file.Close()
|
||||
if err != nil {
|
||||
c.Err = model.NewAppError("uploadProfileImage", "Could not open image file", err.Error())
|
||||
c.Err = model.NewLocAppError("uploadProfileImage", "api.user.upload_profile_user.open.app_error", nil, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
// Decode image config first to check dimensions before loading the whole thing into memory later on
|
||||
config, _, err := image.DecodeConfig(file)
|
||||
if err != nil {
|
||||
c.Err = model.NewAppError("uploadProfileFile", "Could not decode profile image config.", err.Error())
|
||||
c.Err = model.NewLocAppError("uploadProfileFile", "api.user.upload_profile_user.decode_config.app_error", nil, err.Error())
|
||||
return
|
||||
} else if config.Width*config.Height > MaxImageSize {
|
||||
c.Err = model.NewAppError("uploadProfileFile", "Unable to upload profile image. File is too large.", err.Error())
|
||||
c.Err = model.NewLocAppError("uploadProfileFile", "api.user.upload_profile_user.too_large.app_error", nil, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
@@ -1082,7 +1087,7 @@ func uploadProfileImage(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
// Decode image into Image object
|
||||
img, _, err := image.Decode(file)
|
||||
if err != nil {
|
||||
c.Err = model.NewAppError("uploadProfileImage", "Could not decode profile image", err.Error())
|
||||
c.Err = model.NewLocAppError("uploadProfileImage", "api.user.upload_profile_user.decode.app_error", nil, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
@@ -1092,7 +1097,7 @@ func uploadProfileImage(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
buf := new(bytes.Buffer)
|
||||
err = png.Encode(buf, img)
|
||||
if err != nil {
|
||||
c.Err = model.NewAppError("uploadProfileImage", "Could not encode profile image", err.Error())
|
||||
c.Err = model.NewLocAppError("uploadProfileImage", "api.user.upload_profile_user.encode.app_error", nil, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
@@ -1173,7 +1178,7 @@ func updatePassword(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
if userId != c.Session.UserId {
|
||||
c.Err = model.NewAppError("updatePassword", "Update password failed because context user_id did not match props user_id", "")
|
||||
c.Err = model.NewLocAppError("updatePassword", "api.user.update_password.context.app_error", nil, "")
|
||||
c.Err.StatusCode = http.StatusForbidden
|
||||
return
|
||||
}
|
||||
@@ -1186,7 +1191,7 @@ func updatePassword(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
if result.Data == nil {
|
||||
c.Err = model.NewAppError("updatePassword", "Update password failed because we couldn't find a valid account", "")
|
||||
c.Err = model.NewLocAppError("updatePassword", "api.user.update_password.valid_account.app_error", nil, "")
|
||||
c.Err.StatusCode = http.StatusBadRequest
|
||||
return
|
||||
}
|
||||
@@ -1197,19 +1202,19 @@ func updatePassword(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
if user.AuthData != "" {
|
||||
c.LogAudit("failed - tried to update user password who was logged in through oauth")
|
||||
c.Err = model.NewAppError("updatePassword", "Update password failed because the user is logged in through an OAuth service", "auth_service="+user.AuthService)
|
||||
c.Err = model.NewLocAppError("updatePassword", "api.user.update_password.oauth.app_error", nil, "auth_service="+user.AuthService)
|
||||
c.Err.StatusCode = http.StatusForbidden
|
||||
return
|
||||
}
|
||||
|
||||
if !model.ComparePassword(user.Password, currentPassword) {
|
||||
c.Err = model.NewAppError("updatePassword", "The \"Current Password\" you entered is incorrect. Please check that Caps Lock is off and try again.", "")
|
||||
c.Err = model.NewLocAppError("updatePassword", "api.user.update_password.incorrect.app_error", nil, "")
|
||||
c.Err.StatusCode = http.StatusForbidden
|
||||
return
|
||||
}
|
||||
|
||||
if uresult := <-Srv.Store.User().UpdatePassword(c.Session.UserId, model.HashPassword(newPassword)); uresult.Err != nil {
|
||||
c.Err = model.NewAppError("updatePassword", "Update password failed", uresult.Err.Error())
|
||||
c.Err = model.NewLocAppError("updatePassword", "api.user.update_password.failed.app_error", nil, uresult.Err.Error())
|
||||
c.Err.StatusCode = http.StatusForbidden
|
||||
return
|
||||
} else {
|
||||
@@ -1219,7 +1224,7 @@ func updatePassword(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
l4g.Error(tresult.Err.Message)
|
||||
} else {
|
||||
team := tresult.Data.(*model.Team)
|
||||
sendPasswordChangeEmailAndForget(user.Email, team.DisplayName, c.GetTeamURLFromTeam(team), c.GetSiteURL(), "using the settings menu")
|
||||
sendPasswordChangeEmailAndForget(user.Email, team.DisplayName, c.GetTeamURLFromTeam(team), c.GetSiteURL(), c.T("api.user.update_password.menu"))
|
||||
}
|
||||
|
||||
data := make(map[string]string)
|
||||
@@ -1244,7 +1249,7 @@ func updateRoles(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
if model.IsInRole(new_roles, model.ROLE_SYSTEM_ADMIN) && !c.IsSystemAdmin() {
|
||||
c.Err = model.NewAppError("updateRoles", "The system admin role can only be set by another system admin", "")
|
||||
c.Err = model.NewLocAppError("updateRoles", "api.user.update_roles.system_admin_set.app_error", nil, "")
|
||||
c.Err.StatusCode = http.StatusForbidden
|
||||
return
|
||||
}
|
||||
@@ -1262,13 +1267,13 @@ func updateRoles(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
if !c.IsTeamAdmin() {
|
||||
c.Err = model.NewAppError("updateRoles", "You do not have the appropriate permissions", "userId="+user_id)
|
||||
c.Err = model.NewLocAppError("updateRoles", "api.user.update_roles.permissions.app_error", nil, "userId="+user_id)
|
||||
c.Err.StatusCode = http.StatusForbidden
|
||||
return
|
||||
}
|
||||
|
||||
if user.IsInRole(model.ROLE_SYSTEM_ADMIN) && !c.IsSystemAdmin() {
|
||||
c.Err = model.NewAppError("updateRoles", "The system admin role can only by modified by another system admin", "")
|
||||
c.Err = model.NewLocAppError("updateRoles", "api.user.update_roles.system_admin_mod.app_error", nil, "")
|
||||
c.Err.StatusCode = http.StatusForbidden
|
||||
return
|
||||
}
|
||||
@@ -1320,7 +1325,7 @@ func UpdateRoles(c *Context, user *model.User, roles string) *model.User {
|
||||
}
|
||||
|
||||
if activeAdmins <= 0 {
|
||||
c.Err = model.NewAppError("updateRoles", "There must be at least one active admin", "")
|
||||
c.Err = model.NewLocAppError("updateRoles", "api.user.update_roles.one_admin.app_error", nil, "")
|
||||
return nil
|
||||
}
|
||||
}
|
||||
@@ -1365,7 +1370,7 @@ func updateActive(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
if !c.IsTeamAdmin() {
|
||||
c.Err = model.NewAppError("updateActive", "You do not have the appropriate permissions", "userId="+user_id)
|
||||
c.Err = model.NewLocAppError("updateActive", "api.user.update_active.permissions.app_error", nil, "userId="+user_id)
|
||||
c.Err.StatusCode = http.StatusForbidden
|
||||
return
|
||||
}
|
||||
@@ -1385,7 +1390,7 @@ func updateActive(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
if activeAdmins <= 0 {
|
||||
c.Err = model.NewAppError("updateRoles", "There must be at least one active admin", "userId="+user_id)
|
||||
c.Err = model.NewLocAppError("updateRoles", "api.user.update_roles.one_admin.app_error", nil, "userId="+user_id)
|
||||
return
|
||||
}
|
||||
}
|
||||
@@ -1424,12 +1429,12 @@ func UpdateActive(c *Context, user *model.User, active bool) *model.User {
|
||||
}
|
||||
|
||||
func PermanentDeleteUser(c *Context, user *model.User) *model.AppError {
|
||||
l4g.Warn("Attempting to permanently delete account %v id=%v", user.Email, user.Id)
|
||||
l4g.Warn(utils.T("api.user.permanent_delete_user.attempting.warn"), user.Email, user.Id)
|
||||
c.Path = "/users/permanent_delete"
|
||||
c.LogAuditWithUserId(user.Id, fmt.Sprintf("attempt userId=%v", user.Id))
|
||||
c.LogAuditWithUserId("", fmt.Sprintf("attempt userId=%v", user.Id))
|
||||
if user.IsInRole(model.ROLE_SYSTEM_ADMIN) {
|
||||
l4g.Warn("You are deleting %v that is a system administrator. You may need to set another account as the system administrator using the command line tools.", user.Email)
|
||||
l4g.Warn(utils.T("api.user.permanent_delete_user.system_admin.warn"), user.Email)
|
||||
}
|
||||
|
||||
UpdateActive(c, user, false)
|
||||
@@ -1474,7 +1479,7 @@ func PermanentDeleteUser(c *Context, user *model.User) *model.AppError {
|
||||
return result.Err
|
||||
}
|
||||
|
||||
l4g.Warn("Permanently deleted account %v id=%v", user.Email, user.Id)
|
||||
l4g.Warn(utils.T("api.user.permanent_delete_user.deleted.warn"), user.Email, user.Id)
|
||||
c.LogAuditWithUserId("", fmt.Sprintf("success userId=%v", user.Id))
|
||||
|
||||
return nil
|
||||
@@ -1505,14 +1510,14 @@ func sendPasswordReset(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
var user *model.User
|
||||
if result := <-Srv.Store.User().GetByEmail(team.Id, email); result.Err != nil {
|
||||
c.Err = model.NewAppError("sendPasswordReset", "We couldn’t find an account with that address.", "email="+email+" team_id="+team.Id)
|
||||
c.Err = model.NewLocAppError("sendPasswordReset", "api.user.send_password_reset.find.app_error", nil, "email="+email+" team_id="+team.Id)
|
||||
return
|
||||
} else {
|
||||
user = result.Data.(*model.User)
|
||||
}
|
||||
|
||||
if len(user.AuthData) != 0 {
|
||||
c.Err = model.NewAppError("sendPasswordReset", "Cannot reset password for SSO accounts", "userId="+user.Id+", teamId="+team.Id)
|
||||
c.Err = model.NewLocAppError("sendPasswordReset", "api.user.send_password_reset.sso.app_error", nil, "userId="+user.Id+", teamId="+team.Id)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -1532,7 +1537,7 @@ func sendPasswordReset(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
bodyPage.Props["ResetUrl"] = link
|
||||
|
||||
if err := utils.SendMail(email, subjectPage.Render(), bodyPage.Render()); err != nil {
|
||||
c.Err = model.NewAppError("sendPasswordReset", "Failed to send password reset email successfully", "err="+err.Message)
|
||||
c.Err = model.NewLocAppError("sendPasswordReset", "api.user.send_password_reset.send.app_error", nil, "err="+err.Message)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -1601,25 +1606,25 @@ func resetPassword(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
if len(user.AuthData) != 0 {
|
||||
c.Err = model.NewAppError("resetPassword", "Cannot reset password for SSO accounts", "userId="+user.Id+", teamId="+team.Id)
|
||||
c.Err = model.NewLocAppError("resetPassword", "api.user.reset_password.sso.app_error", nil, "userId="+user.Id+", teamId="+team.Id)
|
||||
return
|
||||
}
|
||||
|
||||
if user.TeamId != team.Id {
|
||||
c.Err = model.NewAppError("resetPassword", "Trying to reset password for user on wrong team.", "userId="+user.Id+", teamId="+team.Id)
|
||||
c.Err = model.NewLocAppError("resetPassword", "api.user.reset_password.wrong_team.app_error", nil, "userId="+user.Id+", teamId="+team.Id)
|
||||
c.Err.StatusCode = http.StatusForbidden
|
||||
return
|
||||
}
|
||||
|
||||
if !c.IsSystemAdmin() {
|
||||
if !model.ComparePassword(hash, fmt.Sprintf("%v:%v", props["data"], utils.Cfg.EmailSettings.PasswordResetSalt)) {
|
||||
c.Err = model.NewAppError("resetPassword", "The reset password link does not appear to be valid", "")
|
||||
c.Err = model.NewLocAppError("resetPassword", "api.user.reset_password.invalid_link.app_error", nil, "")
|
||||
return
|
||||
}
|
||||
|
||||
t, err := strconv.ParseInt(timeStr, 10, 64)
|
||||
if err != nil || model.GetMillis()-t > 1000*60*60 { // one hour
|
||||
c.Err = model.NewAppError("resetPassword", "The reset link has expired", "")
|
||||
c.Err = model.NewLocAppError("resetPassword", "api.user.reset_password.link_expired.app_error", nil, "")
|
||||
return
|
||||
}
|
||||
}
|
||||
@@ -1650,7 +1655,7 @@ func sendPasswordChangeEmailAndForget(email, teamDisplayName, teamURL, siteURL,
|
||||
bodyPage.Props["Method"] = method
|
||||
|
||||
if err := utils.SendMail(email, subjectPage.Render(), bodyPage.Render()); err != nil {
|
||||
l4g.Error("Failed to send update password email successfully err=%v", err)
|
||||
l4g.Error(utils.T("api.user.send_password_change_email_and_forget.error"), err)
|
||||
}
|
||||
|
||||
}()
|
||||
@@ -1669,7 +1674,7 @@ func sendEmailChangeEmailAndForget(oldEmail, newEmail, teamDisplayName, teamURL,
|
||||
bodyPage.Props["NewEmail"] = newEmail
|
||||
|
||||
if err := utils.SendMail(oldEmail, subjectPage.Render(), bodyPage.Render()); err != nil {
|
||||
l4g.Error("Failed to send email change notification email successfully err=%v", err)
|
||||
l4g.Error(utils.T("api.user.send_email_change_email_and_forget.error"), err)
|
||||
}
|
||||
|
||||
}()
|
||||
@@ -1689,7 +1694,7 @@ func SendEmailChangeVerifyEmailAndForget(userId, newUserEmail, teamName, teamDis
|
||||
bodyPage.Props["VerifyUrl"] = link
|
||||
|
||||
if err := utils.SendMail(newUserEmail, subjectPage.Render(), bodyPage.Render()); err != nil {
|
||||
l4g.Error("Failed to send email change verification email successfully err=%v", err)
|
||||
l4g.Error(utils.T("api.user.send_email_change_verify_email_and_forget.error"), err)
|
||||
}
|
||||
}()
|
||||
}
|
||||
@@ -1798,7 +1803,7 @@ func GetAuthorizationCode(c *Context, service, teamName string, props map[string
|
||||
|
||||
sso := utils.Cfg.GetSSOService(service)
|
||||
if sso != nil && !sso.Enable {
|
||||
return "", model.NewAppError("GetAuthorizationCode", "Unsupported OAuth service provider", "service="+service)
|
||||
return "", model.NewLocAppError("GetAuthorizationCode", "api.user.get_authorization_code.unsupported.app_error", nil, "service="+service)
|
||||
}
|
||||
|
||||
clientId := sso.Id
|
||||
@@ -1827,12 +1832,12 @@ func GetAuthorizationCode(c *Context, service, teamName string, props map[string
|
||||
func AuthorizeOAuthUser(service, code, state, redirectUri string) (io.ReadCloser, *model.Team, map[string]string, *model.AppError) {
|
||||
sso := utils.Cfg.GetSSOService(service)
|
||||
if sso == nil || !sso.Enable {
|
||||
return nil, nil, nil, model.NewAppError("AuthorizeOAuthUser", "Unsupported OAuth service provider", "service="+service)
|
||||
return nil, nil, nil, model.NewLocAppError("AuthorizeOAuthUser", "api.user.authorize_oauth_user.unsupported.app_error", nil, "service="+service)
|
||||
}
|
||||
|
||||
stateStr := ""
|
||||
if b, err := b64.StdEncoding.DecodeString(state); err != nil {
|
||||
return nil, nil, nil, model.NewAppError("AuthorizeOAuthUser", "Invalid state", err.Error())
|
||||
return nil, nil, nil, model.NewLocAppError("AuthorizeOAuthUser", "api.user.authorize_oauth_user.invalid_state.app_error", nil, err.Error())
|
||||
} else {
|
||||
stateStr = string(b)
|
||||
}
|
||||
@@ -1840,13 +1845,13 @@ func AuthorizeOAuthUser(service, code, state, redirectUri string) (io.ReadCloser
|
||||
stateProps := model.MapFromJson(strings.NewReader(stateStr))
|
||||
|
||||
if !model.ComparePassword(stateProps["hash"], sso.Id) {
|
||||
return nil, nil, nil, model.NewAppError("AuthorizeOAuthUser", "Invalid state", "")
|
||||
return nil, nil, nil, model.NewLocAppError("AuthorizeOAuthUser", "api.user.authorize_oauth_user.invalid_state.app_error", nil, "")
|
||||
}
|
||||
|
||||
ok := true
|
||||
teamName := ""
|
||||
if teamName, ok = stateProps["team"]; !ok {
|
||||
return nil, nil, nil, model.NewAppError("AuthorizeOAuthUser", "Invalid state; missing team name", "")
|
||||
return nil, nil, nil, model.NewLocAppError("AuthorizeOAuthUser", "api.user.authorize_oauth_user.invalid_state_team.app_error", nil, "")
|
||||
}
|
||||
|
||||
tchan := Srv.Store.Team().GetByName(teamName)
|
||||
@@ -1866,20 +1871,20 @@ func AuthorizeOAuthUser(service, code, state, redirectUri string) (io.ReadCloser
|
||||
|
||||
var ar *model.AccessResponse
|
||||
if resp, err := client.Do(req); err != nil {
|
||||
return nil, nil, nil, model.NewAppError("AuthorizeOAuthUser", "Token request failed", err.Error())
|
||||
return nil, nil, nil, model.NewLocAppError("AuthorizeOAuthUser", "api.user.authorize_oauth_user.token_failed.app_error", nil, err.Error())
|
||||
} else {
|
||||
ar = model.AccessResponseFromJson(resp.Body)
|
||||
if ar == nil {
|
||||
return nil, nil, nil, model.NewAppError("AuthorizeOAuthUser", "Bad response from token request", "")
|
||||
return nil, nil, nil, model.NewLocAppError("AuthorizeOAuthUser", "api.user.authorize_oauth_user.bad_response.app_error", nil, "")
|
||||
}
|
||||
}
|
||||
|
||||
if strings.ToLower(ar.TokenType) != model.ACCESS_TOKEN_TYPE {
|
||||
return nil, nil, nil, model.NewAppError("AuthorizeOAuthUser", "Bad token type", "token_type="+ar.TokenType)
|
||||
return nil, nil, nil, model.NewLocAppError("AuthorizeOAuthUser", "api.user.authorize_oauth_user.bad_token.app_error", nil, "token_type="+ar.TokenType)
|
||||
}
|
||||
|
||||
if len(ar.AccessToken) == 0 {
|
||||
return nil, nil, nil, model.NewAppError("AuthorizeOAuthUser", "Missing access token", "")
|
||||
return nil, nil, nil, model.NewLocAppError("AuthorizeOAuthUser", "api.user.authorize_oauth_user.missing.app_error", nil, "")
|
||||
}
|
||||
|
||||
p = url.Values{}
|
||||
@@ -1891,7 +1896,8 @@ func AuthorizeOAuthUser(service, code, state, redirectUri string) (io.ReadCloser
|
||||
req.Header.Set("Authorization", "Bearer "+ar.AccessToken)
|
||||
|
||||
if resp, err := client.Do(req); err != nil {
|
||||
return nil, nil, nil, model.NewAppError("AuthorizeOAuthUser", "Token request to "+service+" failed", err.Error())
|
||||
return nil, nil, nil, model.NewLocAppError("AuthorizeOAuthUser", "api.user.authorize_oauth_user.service.app_error",
|
||||
map[string]interface{}{"Service": service}, err.Error())
|
||||
} else {
|
||||
if result := <-tchan; result.Err != nil {
|
||||
return nil, nil, nil, result.Err
|
||||
@@ -1990,19 +1996,21 @@ func CompleteSwitchWithOAuth(c *Context, w http.ResponseWriter, r *http.Request,
|
||||
authData := ""
|
||||
provider := einterfaces.GetOauthProvider(service)
|
||||
if provider == nil {
|
||||
c.Err = model.NewAppError("CompleteClaimWithOAuth", service+" oauth not avlailable on this server", "")
|
||||
c.Err = model.NewLocAppError("CompleteClaimWithOAuth", "api.user.complete_switch_with_oauth.unavailable.app_error",
|
||||
map[string]interface{}{"Service": service}, "")
|
||||
return
|
||||
} else {
|
||||
authData = provider.GetAuthDataFromJson(userData)
|
||||
}
|
||||
|
||||
if len(authData) == 0 {
|
||||
c.Err = model.NewAppError("CompleteClaimWithOAuth", "Could not parse auth data out of "+service+" user object", "")
|
||||
c.Err = model.NewLocAppError("CompleteClaimWithOAuth", "api.user.complete_switch_with_oauth.parse.app_error",
|
||||
map[string]interface{}{"Service": service}, "")
|
||||
return
|
||||
}
|
||||
|
||||
if len(email) == 0 {
|
||||
c.Err = model.NewAppError("CompleteClaimWithOAuth", "Blank email", "")
|
||||
c.Err = model.NewLocAppError("CompleteClaimWithOAuth", "api.user.complete_switch_with_oauth.blank_email.app_error", nil, "")
|
||||
return
|
||||
}
|
||||
|
||||
@@ -2070,7 +2078,7 @@ func switchToEmail(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
if user.Id != c.Session.UserId {
|
||||
c.LogAudit("fail - user ids didn't match")
|
||||
c.Err = model.NewAppError("switchToEmail", "Update password failed because context user_id did not match provided user's id", "")
|
||||
c.Err = model.NewLocAppError("switchToEmail", "api.user.switch_to_email.context.app_error", nil, "")
|
||||
c.Err.StatusCode = http.StatusForbidden
|
||||
return
|
||||
}
|
||||
@@ -2108,7 +2116,7 @@ func sendSignInChangeEmailAndForget(email, teamDisplayName, teamURL, siteURL, me
|
||||
bodyPage.Props["Method"] = method
|
||||
|
||||
if err := utils.SendMail(email, subjectPage.Render(), bodyPage.Render()); err != nil {
|
||||
l4g.Error("Failed to send update password email successfully err=%v", err)
|
||||
l4g.Error(utils.T("api.user.send_sign_in_change_email_and_forget.error"), err)
|
||||
}
|
||||
|
||||
}()
|
||||
|
||||
Ссылка в новой задаче
Block a user