func revokeAllSessions(c *Context, w http.ResponseWriter, r *http.Request) { props := model.MapFromJson(r.Body) id := props["id"] if result := <-Srv.Store.Session().Get(id); result.Err != nil { c.Err = result.Err return } else { session := result.Data.(*model.Session) c.LogAudit("revoked_all=" + id) if session.IsOAuth { RevokeAccessToken(session.Token) } else { sessionCache.Remove(session.Token) if result := <-Srv.Store.Session().Remove(session.Id); result.Err != nil { c.Err = result.Err return } else { w.Write([]byte(model.MapToJson(props))) return } } } }
func signupTeam(c *Context, w http.ResponseWriter, r *http.Request) { m := model.MapFromJson(r.Body) email := strings.ToLower(strings.TrimSpace(m["email"])) if len(email) == 0 { c.SetInvalidParam("signupTeam", "email") return } subjectPage := NewServerTemplatePage("signup_team_subject", c.GetSiteURL()) bodyPage := NewServerTemplatePage("signup_team_body", c.GetSiteURL()) bodyPage.Props["TourUrl"] = utils.Cfg.TeamSettings.TourLink props := make(map[string]string) props["email"] = email props["time"] = fmt.Sprintf("%v", model.GetMillis()) data := model.MapToJson(props) hash := model.HashPassword(fmt.Sprintf("%v:%v", data, utils.Cfg.ServiceSettings.InviteSalt)) bodyPage.Props["Link"] = fmt.Sprintf("%s/signup_team_complete/?d=%s&h=%s", c.GetSiteURL(), url.QueryEscape(data), url.QueryEscape(hash)) if err := utils.SendMail(email, subjectPage.Render(), bodyPage.Render()); err != nil { c.Err = err return } if utils.Cfg.ServiceSettings.Mode == utils.MODE_DEV || utils.Cfg.EmailSettings.ByPassEmail { m["follow_link"] = bodyPage.Props["Link"] } w.Header().Set("Access-Control-Allow-Origin", " *") w.Write([]byte(model.MapToJson(m))) }
func emailTeams(c *Context, w http.ResponseWriter, r *http.Request) { m := model.MapFromJson(r.Body) email := strings.ToLower(strings.TrimSpace(m["email"])) if email == "" { c.SetInvalidParam("findTeam", "email") return } subjectPage := NewServerTemplatePage("find_teams_subject") subjectPage.Props["SiteURL"] = c.GetSiteURL() bodyPage := NewServerTemplatePage("find_teams_body") bodyPage.Props["SiteURL"] = c.GetSiteURL() if result := <-Srv.Store.Team().GetTeamsForEmail(email); result.Err != nil { c.Err = result.Err } else { teams := result.Data.([]*model.Team) // the template expects Props to be a map with team names as the keys and the team url as the value props := make(map[string]string) for _, team := range teams { props[team.Name] = c.GetTeamURLFromTeam(team) } 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) } w.Write([]byte(model.MapToJson(m))) } }
func getTeamIdFromQuery(query url.Values) (string, *model.AppError) { hash := query.Get("h") inviteId := query.Get("id") if len(hash) > 0 { data := query.Get("d") props := model.MapFromJson(strings.NewReader(data)) if !model.ComparePassword(hash, fmt.Sprintf("%v:%v", data, utils.Cfg.EmailSettings.InviteSalt)) { return "", model.NewLocAppError("getTeamIdFromQuery", "api.oauth.singup_with_oauth.invalid_link.app_error", nil, "") } t, err := strconv.ParseInt(props["time"], 10, 64) if err != nil || model.GetMillis()-t > 1000*60*60*48 { // 48 hours return "", model.NewLocAppError("getTeamIdFromQuery", "api.oauth.singup_with_oauth.expired_link.app_error", nil, "") } return props["id"], nil } else if len(inviteId) > 0 { if result := <-Srv.Store.Team().GetByInviteId(inviteId); result.Err != nil { // soft fail, so we still create user but don't auto-join team l4g.Error("%v", result.Err) } else { return result.Data.(*model.Team).Id, nil } } return "", nil }
func removeChannelMember(c *Context, w http.ResponseWriter, r *http.Request) { params := mux.Vars(r) id := params["id"] data := model.MapFromJson(r.Body) userId := data["user_id"] if len(userId) != 26 { c.SetInvalidParam("addChannelMember", "user_id") return } sc := Srv.Store.Channel().Get(id) cmc := Srv.Store.Channel().GetMember(id, c.Session.UserId) if cresult := <-sc; cresult.Err != nil { c.Err = cresult.Err return } else if cmcresult := <-cmc; cmcresult.Err != nil { c.Err = cmcresult.Err return } else { channel := cresult.Data.(*model.Channel) channelMember := cmcresult.Data.(model.ChannelMember) if !c.HasPermissionsToTeam(channel.TeamId, "removeChannelMember") { return } if !strings.Contains(channelMember.Roles, model.CHANNEL_ROLE_ADMIN) && !strings.Contains(c.Session.Roles, model.ROLE_ADMIN) { c.Err = model.NewAppError("updateChannel", "You do not have the appropriate permissions ", "") c.Err.StatusCode = http.StatusForbidden return } if channel.DeleteAt > 0 { c.Err = model.NewAppError("updateChannel", "The channel has been archived or deleted", "") c.Err.StatusCode = http.StatusBadRequest return } if cmresult := <-Srv.Store.Channel().RemoveMember(id, userId); cmresult.Err != nil { c.Err = cmresult.Err return } message := model.NewMessage(c.Session.TeamId, "", userId, model.ACTION_USER_REMOVED) message.Add("channel_id", id) message.Add("remover", c.Session.UserId) PublishAndForget(message) c.LogAudit("name=" + channel.Name + " user_id=" + userId) result := make(map[string]string) result["channel_id"] = channel.Id result["removed_user_id"] = userId w.Write([]byte(model.MapToJson(result))) } }
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.StatusCode = http.StatusForbidden return } var user *model.User if len(props["id"]) != 0 { user = LoginById(c, w, r, props["id"], props["password"], props["device_id"]) } 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.StatusCode = http.StatusForbidden return } if c.Err != nil { return } if user != nil { user.Sanitize(map[string]bool{}) } else { user = &model.User{} } w.Write([]byte(user.ToJson())) }
func updateTeamDisplayName(c *Context, w http.ResponseWriter, r *http.Request) { props := model.MapFromJson(r.Body) new_name := props["new_name"] if len(new_name) == 0 { c.SetInvalidParam("updateTeamDisplayName", "new_name") return } teamId := props["team_id"] if len(teamId) > 0 && len(teamId) != 26 { c.SetInvalidParam("updateTeamDisplayName", "team_id") return } else if len(teamId) == 0 { teamId = c.Session.TeamId } if !c.HasPermissionsToTeam(teamId, "updateTeamDisplayName") { return } if !model.IsInRole(c.Session.Roles, model.ROLE_TEAM_ADMIN) { c.Err = model.NewAppError("updateTeamDisplayName", "You do not have the appropriate permissions", "userId="+c.Session.UserId) c.Err.StatusCode = http.StatusForbidden return } if result := <-Srv.Store.Team().UpdateDisplayName(new_name, c.Session.TeamId); result.Err != nil { c.Err = result.Err return } w.Write([]byte(model.MapToJson(props))) }
func findTeams(c *Context, w http.ResponseWriter, r *http.Request) { m := model.MapFromJson(r.Body) email := strings.ToLower(strings.TrimSpace(m["email"])) if email == "" { c.SetInvalidParam("findTeam", "email") return } if result := <-Srv.Store.Team().GetTeamsForEmail(email); result.Err != nil { c.Err = result.Err return } else { teams := result.Data.([]*model.Team) s := make([]string, 0, len(teams)) for _, v := range teams { s = append(s, v.Name) } w.Write([]byte(model.ArrayToJson(s))) } }
func revokeSession(c *Context, w http.ResponseWriter, r *http.Request) { props := model.MapFromJson(r.Body) altId := props["id"] if result := <-Srv.Store.Session().GetSessions(c.Session.UserId); result.Err != nil { c.Err = result.Err return } else { sessions := result.Data.([]*model.Session) for _, session := range sessions { if session.AltId == altId { c.LogAudit("session_id=" + session.AltId) sessionCache.Remove(session.Id) if result := <-Srv.Store.Session().Remove(session.Id); result.Err != nil { c.Err = result.Err return } else { w.Write([]byte(model.MapToJson(props))) return } } } } }
func findTeams(c *Context, w http.ResponseWriter, r *http.Request) { m := model.MapFromJson(r.Body) email := strings.ToLower(strings.TrimSpace(m["email"])) if email == "" { c.SetInvalidParam("findTeam", "email") return } if result := <-Srv.Store.Team().GetTeamsForEmail(email); result.Err != nil { c.Err = result.Err return } else { teams := result.Data.([]*model.Team) m := make(map[string]*model.Team) for _, v := range teams { v.Sanitize() m[v.Id] = v } w.Write([]byte(model.TeamMapToJson(m))) } }
func command(c *Context, w http.ResponseWriter, r *http.Request) { props := model.MapFromJson(r.Body) command := &model.Command{ Command: strings.TrimSpace(props["command"]), ChannelId: strings.TrimSpace(props["channelId"]), Suggest: props["suggest"] == "true", Suggestions: make([]*model.SuggestCommand, 0, 128), } checkCommand(c, command) if c.Err != nil { if c.Err != commandNotImplementedErr { return } else { c.Err = nil command.Response = model.RESP_NOT_IMPLEMENTED w.Write([]byte(command.ToJson())) return } } else { w.Write([]byte(command.ToJson())) } }
func sendPasswordReset(c *Context, w http.ResponseWriter, r *http.Request) { props := model.MapFromJson(r.Body) email := props["email"] if len(email) == 0 { c.SetInvalidParam("sendPasswordReset", "email") return } name := props["name"] if len(name) == 0 { c.SetInvalidParam("sendPasswordReset", "name") return } var team *model.Team if result := <-Srv.Store.Team().GetByName(name); result.Err != nil { c.Err = result.Err return } else { team = result.Data.(*model.Team) } 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) 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) return } newProps := make(map[string]string) newProps["user_id"] = user.Id newProps["time"] = fmt.Sprintf("%v", model.GetMillis()) data := model.MapToJson(newProps) hash := model.HashPassword(fmt.Sprintf("%v:%v", data, utils.Cfg.EmailSettings.PasswordResetSalt)) link := fmt.Sprintf("%s/reset_password?d=%s&h=%s", c.GetTeamURLFromTeam(team), url.QueryEscape(data), url.QueryEscape(hash)) subjectPage := NewServerTemplatePage("reset_subject") subjectPage.Props["SiteURL"] = c.GetSiteURL() bodyPage := NewServerTemplatePage("reset_body") bodyPage.Props["SiteURL"] = c.GetSiteURL() 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) return } c.LogAuditWithUserId(user.Id, "sent="+email) w.Write([]byte(model.MapToJson(props))) }
func adminResetPassword(c *Context, w http.ResponseWriter, r *http.Request) { props := model.MapFromJson(r.Body) userId := props["user_id"] if len(userId) != 26 { c.SetInvalidParam("adminResetPassword", "user_id") return } newPassword := props["new_password"] if err := utils.IsPasswordValid(newPassword); err != nil { c.Err = err return } if err := ResetPassword(c, userId, newPassword); err != nil { c.Err = err return } c.LogAudit("") rdata := map[string]string{} rdata["status"] = "ok" w.Write([]byte(model.MapToJson(rdata))) }
func removeMember(c *Context, w http.ResponseWriter, r *http.Request) { params := mux.Vars(r) channelId := params["channel_id"] data := model.MapFromJson(r.Body) userIdToRemove := data["user_id"] if len(userIdToRemove) != 26 { c.SetInvalidParam("removeMember", "user_id") return } sc := Srv.Store.Channel().Get(channelId) cmc := Srv.Store.Channel().GetMember(channelId, c.Session.UserId) ouc := Srv.Store.User().Get(userIdToRemove) if oresult := <-ouc; oresult.Err != nil { c.Err = model.NewLocAppError("removeMember", "api.channel.remove_member.user.app_error", nil, "") return } else { oUser := oresult.Data.(*model.User) if cresult := <-sc; cresult.Err != nil { c.Err = cresult.Err return } else if cmcresult := <-cmc; cmcresult.Err != nil { c.Err = cmcresult.Err return } else { channel := cresult.Data.(*model.Channel) removerChannelMember := cmcresult.Data.(model.ChannelMember) if !c.HasPermissionsToTeam(channel.TeamId, "removeMember") { return } if !strings.Contains(removerChannelMember.Roles, model.CHANNEL_ROLE_ADMIN) && !c.IsTeamAdmin() { 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.NewLocAppError("updateChannel", "api.channel.remove_member.unable.app_error", nil, err.Message) return } c.LogAudit("name=" + channel.Name + " user_id=" + userIdToRemove) go PostUserAddRemoveMessage(c, channel.Id, fmt.Sprintf(utils.T("api.channel.remove_member.removed"), oUser.Username), model.POST_ADD_REMOVE) result := make(map[string]string) result["channel_id"] = channel.Id result["removed_user_id"] = userIdToRemove w.Write([]byte(model.MapToJson(result))) } } }
func updateUserNotify(c *Context, w http.ResponseWriter, r *http.Request) { props := model.MapFromJson(r.Body) user_id := props["user_id"] if len(user_id) != 26 { c.SetInvalidParam("updateUserNotify", "user_id") return } uchan := Srv.Store.User().Get(user_id) if !c.HasPermissionsToUser(user_id, "updateUserNotify") { return } delete(props, "user_id") email := props["email"] if len(email) == 0 { c.SetInvalidParam("updateUserNotify", "email") return } desktop_sound := props["desktop_sound"] if len(desktop_sound) == 0 { c.SetInvalidParam("updateUserNotify", "desktop_sound") return } desktop := props["desktop"] if len(desktop) == 0 { c.SetInvalidParam("updateUserNotify", "desktop") return } var user *model.User if result := <-uchan; result.Err != nil { c.Err = result.Err return } else { user = result.Data.(*model.User) } user.NotifyProps = props if result := <-Srv.Store.User().Update(user, false); result.Err != nil { c.Err = result.Err return } else { c.LogAuditWithUserId(user.Id, "") ruser := result.Data.([2]*model.User)[0] options := utils.SanitizeOptions options["passwordupdate"] = false ruser.Sanitize(options) w.Write([]byte(ruser.ToJson())) } }
func signupWithOAuth(c *api.Context, w http.ResponseWriter, r *http.Request) { params := mux.Vars(r) service := params["service"] teamName := params["team"] if !utils.Cfg.TeamSettings.EnableUserCreation { c.Err = model.NewAppError("signupTeam", "User sign-up is disabled.", "") c.Err.StatusCode = http.StatusNotImplemented return } if len(teamName) == 0 { c.Err = model.NewAppError("signupWithOAuth", "Invalid team name", "team_name="+teamName) c.Err.StatusCode = http.StatusBadRequest return } hash := r.URL.Query().Get("h") var team *model.Team if result := <-api.Srv.Store.Team().GetByName(teamName); result.Err != nil { c.Err = result.Err return } else { team = result.Data.(*model.Team) } if api.IsVerifyHashRequired(nil, team, hash) { data := r.URL.Query().Get("d") props := model.MapFromJson(strings.NewReader(data)) if !model.ComparePassword(hash, fmt.Sprintf("%v:%v", data, utils.Cfg.EmailSettings.InviteSalt)) { c.Err = model.NewAppError("signupWithOAuth", "The signup link does not appear to be valid", "") 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("signupWithOAuth", "The signup link has expired", "") return } if team.Id != props["id"] { c.Err = model.NewAppError("signupWithOAuth", "Invalid team name", data) return } } stateProps := map[string]string{} stateProps["action"] = model.OAUTH_ACTION_SIGNUP if authUrl, err := api.GetAuthorizationCode(c, service, teamName, stateProps, ""); err != nil { c.Err = err return } else { http.Redirect(w, r, authUrl, http.StatusFound) } }
func updateActive(c *Context, w http.ResponseWriter, r *http.Request) { props := model.MapFromJson(r.Body) user_id := props["user_id"] if len(user_id) != 26 { c.SetInvalidParam("updateActive", "user_id") return } active := props["active"] == "true" var user *model.User if result := <-Srv.Store.User().Get(user_id); result.Err != nil { c.Err = result.Err return } else { user = result.Data.(*model.User) } if !c.HasPermissionsToTeam(user.TeamId, "updateActive") { return } if !c.IsTeamAdmin() { c.Err = model.NewAppError("updateActive", "You do not have the appropriate permissions", "userId="+user_id) c.Err.StatusCode = http.StatusForbidden return } // make sure there is at least 1 other active admin if !active && model.IsInRole(user.Roles, model.ROLE_TEAM_ADMIN) { if result := <-Srv.Store.User().GetProfiles(user.TeamId); result.Err != nil { c.Err = result.Err return } else { activeAdmins := -1 profileUsers := result.Data.(map[string]*model.User) for _, profileUser := range profileUsers { if profileUser.DeleteAt == 0 && model.IsInRole(profileUser.Roles, model.ROLE_TEAM_ADMIN) { activeAdmins = activeAdmins + 1 } } if activeAdmins <= 0 { c.Err = model.NewAppError("updateRoles", "There must be at least one active admin", "userId="+user_id) return } } } ruser := UpdateActive(c, user, active) if c.Err == nil { w.Write([]byte(ruser.ToJson())) } }
func removeMember(c *Context, w http.ResponseWriter, r *http.Request) { params := mux.Vars(r) channelId := params["channel_id"] data := model.MapFromJson(r.Body) userIdToRemove := data["user_id"] if len(userIdToRemove) != 26 { c.SetInvalidParam("removeMember", "user_id") return } sc := Srv.Store.Channel().Get(channelId) cmc := Srv.Store.Channel().GetMember(channelId, c.Session.UserId) ouc := Srv.Store.User().Get(userIdToRemove) if oresult := <-ouc; oresult.Err != nil { c.Err = model.NewLocAppError("removeMember", "api.channel.remove_member.user.app_error", nil, "") return } else { oUser := oresult.Data.(*model.User) if cresult := <-sc; cresult.Err != nil { c.Err = cresult.Err return } else if cmcresult := <-cmc; cmcresult.Err != nil { c.Err = cmcresult.Err return } else { channel := cresult.Data.(*model.Channel) if channel.Type == model.CHANNEL_OPEN && !HasPermissionToChannelContext(c, channel.Id, model.PERMISSION_MANAGE_PUBLIC_CHANNEL_MEMBERS) { return } if channel.Type == model.CHANNEL_PRIVATE && !HasPermissionToChannelContext(c, channel.Id, model.PERMISSION_MANAGE_PRIVATE_CHANNEL_MEMBERS) { return } if err := RemoveUserFromChannel(userIdToRemove, c.Session.UserId, channel); err != nil { c.Err = model.NewLocAppError("updateChannel", "api.channel.remove_member.unable.app_error", nil, err.Message) return } c.LogAudit("name=" + channel.Name + " user_id=" + userIdToRemove) go PostUserAddRemoveMessage(c, channel.Id, fmt.Sprintf(utils.T("api.channel.remove_member.removed"), oUser.Username), model.POST_ADD_REMOVE) result := make(map[string]string) result["channel_id"] = channel.Id result["removed_user_id"] = userIdToRemove w.Write([]byte(model.MapToJson(result))) } } }
func updateMemberRoles(c *Context, w http.ResponseWriter, r *http.Request) { props := model.MapFromJson(r.Body) userId := props["user_id"] if len(userId) != 26 { c.SetInvalidParam("updateMemberRoles", "user_id") return } mchan := Srv.Store.Team().GetTeamsForUser(userId) teamId := c.TeamId newRoles := props["new_roles"] if !(model.IsValidUserRoles(newRoles)) { c.SetInvalidParam("updateMemberRoles", "new_roles") return } if !HasPermissionToTeamContext(c, teamId, model.PERMISSION_MANAGE_ROLES) { return } var member *model.TeamMember if result := <-mchan; result.Err != nil { c.Err = result.Err return } else { members := result.Data.([]*model.TeamMember) for _, m := range members { if m.TeamId == teamId { member = m } } } if member == nil { c.Err = model.NewLocAppError("updateMemberRoles", "api.team.update_member_roles.not_a_member", nil, "userId="+userId+" teamId="+teamId) c.Err.StatusCode = http.StatusBadRequest return } member.Roles = newRoles if result := <-Srv.Store.Team().UpdateMember(member); result.Err != nil { c.Err = result.Err return } RemoveAllSessionsForUserId(userId) rdata := map[string]string{} rdata["status"] = "ok" w.Write([]byte(model.MapToJson(rdata))) }
func removeCertificate(c *Context, w http.ResponseWriter, r *http.Request) { props := model.MapFromJson(r.Body) filename := props["filename"] if err := os.Remove(utils.FindConfigFile(filename)); err != nil { c.Err = model.NewLocAppError("removeCertificate", "api.admin.remove_certificate.delete.app_error", map[string]interface{}{"Filename": filename}, err.Error()) return } ReturnStatusOK(w) }
func addMember(c *Context, w http.ResponseWriter, r *http.Request) { params := mux.Vars(r) id := params["channel_id"] data := model.MapFromJson(r.Body) userId := data["user_id"] if len(userId) != 26 { c.SetInvalidParam("addMember", "user_id") return } sc := Srv.Store.Channel().Get(id) ouc := Srv.Store.User().Get(c.Session.UserId) nuc := Srv.Store.User().Get(userId) if nresult := <-nuc; nresult.Err != nil { 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.NewLocAppError("addMember", "api.channel.add_member.find_channel.app_error", nil, "") return } else { channel := cresult.Data.(*model.Channel) nUser := nresult.Data.(*model.User) if channel.Type == model.CHANNEL_OPEN && !HasPermissionToChannelContext(c, channel.Id, model.PERMISSION_MANAGE_PUBLIC_CHANNEL_MEMBERS) { return } if channel.Type == model.CHANNEL_PRIVATE && !HasPermissionToChannelContext(c, channel.Id, model.PERMISSION_MANAGE_PRIVATE_CHANNEL_MEMBERS) { return } if oresult := <-ouc; oresult.Err != nil { c.Err = model.NewLocAppError("addMember", "api.channel.add_member.user_adding.app_error", nil, "") return } else { oUser := oresult.Data.(*model.User) cm, err := AddUserToChannel(nUser, channel) if err != nil { c.Err = err return } c.LogAudit("name=" + channel.Name + " user_id=" + userId) go PostUserAddRemoveMessage(c, channel.Id, fmt.Sprintf(utils.T("api.channel.add_member.added"), nUser.Username, oUser.Username), model.POST_ADD_REMOVE) <-Srv.Store.Channel().UpdateLastViewedAt(id, oUser.Id) w.Write([]byte(cm.ToJson())) } } }
func signupWithOAuth(c *Context, w http.ResponseWriter, r *http.Request) { params := mux.Vars(r) service := params["service"] if !utils.Cfg.TeamSettings.EnableUserCreation { c.Err = model.NewLocAppError("signupWithOAuth", "web.singup_with_oauth.disabled.app_error", nil, "") c.Err.StatusCode = http.StatusNotImplemented return } hash := r.URL.Query().Get("h") teamId := "" inviteId := r.URL.Query().Get("id") if len(hash) > 0 { data := r.URL.Query().Get("d") props := model.MapFromJson(strings.NewReader(data)) if !model.ComparePassword(hash, fmt.Sprintf("%v:%v", data, utils.Cfg.EmailSettings.InviteSalt)) { c.Err = model.NewLocAppError("signupWithOAuth", "web.singup_with_oauth.invalid_link.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.NewLocAppError("signupWithOAuth", "web.singup_with_oauth.expired_link.app_error", nil, "") return } teamId = props["id"] } else if len(inviteId) != 0 { if result := <-Srv.Store.Team().GetByInviteId(inviteId); result.Err != nil { // soft fail, so we still create user but don't auto-join team l4g.Error("%v", result.Err) } else { teamId = result.Data.(*model.Team).Id } } stateProps := map[string]string{} stateProps["action"] = model.OAUTH_ACTION_SIGNUP if len(teamId) != 0 { stateProps["team_id"] = teamId } if authUrl, err := GetAuthorizationCode(c, service, stateProps, ""); err != nil { c.Err = err return } else { http.Redirect(w, r, authUrl, http.StatusFound) } }
func addMember(c *Context, w http.ResponseWriter, r *http.Request) { params := mux.Vars(r) id := params["id"] data := model.MapFromJson(r.Body) userId := data["user_id"] if len(userId) != 26 { c.SetInvalidParam("addMember", "user_id") return } cchan := Srv.Store.Channel().CheckPermissionsTo(c.Session.TeamId, id, c.Session.UserId) sc := Srv.Store.Channel().Get(id) ouc := Srv.Store.User().Get(c.Session.UserId) nuc := Srv.Store.User().Get(userId) // Only need to be a member of the channel to add a new member if !c.HasPermissionsToChannel(cchan, "addMember") { return } if nresult := <-nuc; nresult.Err != nil { c.Err = model.NewAppError("addMember", "Failed to find user to be added", "") return } else if cresult := <-sc; cresult.Err != nil { c.Err = model.NewAppError("addMember", "Failed to find channel", "") 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", "") return } else { oUser := oresult.Data.(*model.User) cm, err := AddUserToChannel(nUser, channel) if err != nil { c.Err = err return } 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)) <-Srv.Store.Channel().UpdateLastViewedAt(id, oUser.Id) w.Write([]byte(cm.ToJson())) } } }
func signupUserComplete(c *api.Context, w http.ResponseWriter, r *http.Request) { id := r.FormValue("id") data := r.FormValue("d") hash := r.FormValue("h") var props map[string]string if len(id) > 0 { props = make(map[string]string) if result := <-api.Srv.Store.Team().Get(id); result.Err != nil { c.Err = result.Err return } else { team := result.Data.(*model.Team) if !(team.Type == model.TEAM_OPEN || (team.Type == model.TEAM_INVITE && len(team.AllowedDomains) > 0)) { c.Err = model.NewAppError("signupUserComplete", "The team type doesn't allow open invites", "id="+id) return } props["email"] = "" props["display_name"] = team.DisplayName props["name"] = team.Name props["id"] = team.Id data = model.MapToJson(props) hash = "" } } else { if !model.ComparePassword(hash, fmt.Sprintf("%v:%v", data, utils.Cfg.ServiceSettings.InviteSalt)) { c.Err = model.NewAppError("signupTeamComplete", "The signup link does not appear to be valid", "") return } props = model.MapFromJson(strings.NewReader(data)) t, err := strconv.ParseInt(props["time"], 10, 64) if err != nil || model.GetMillis()-t > 1000*60*60*48 { // 48 hour c.Err = model.NewAppError("signupTeamComplete", "The signup link has expired", "") return } } page := NewHtmlTemplatePage("signup_user_complete", "Complete User Sign Up") page.Props["Email"] = props["email"] page.Props["TeamDisplayName"] = props["display_name"] page.Props["TeamName"] = props["name"] page.Props["TeamId"] = props["id"] page.Props["Data"] = data page.Props["Hash"] = hash page.Props["AuthServices"] = model.ArrayToJson(utils.GetAllowedAuthServices()) page.Render(c, w) }
func signupUserComplete(c *api.Context, w http.ResponseWriter, r *http.Request) { id := r.FormValue("id") data := r.FormValue("d") hash := r.FormValue("h") var props map[string]string if len(id) > 0 { props = make(map[string]string) if result := <-api.Srv.Store.Team().GetByInviteId(id); result.Err != nil { c.Err = result.Err return } else { team := result.Data.(*model.Team) if !(team.Type == model.TEAM_OPEN || (team.Type == model.TEAM_INVITE && len(team.AllowedDomains) > 0)) { c.Err = model.NewLocAppError("signupUserComplete", "web.signup_user_complete.no_invites.app_error", nil, "id="+id) return } props["email"] = "" props["display_name"] = team.DisplayName props["name"] = team.Name props["id"] = team.Id data = model.MapToJson(props) hash = "" } } else { if !model.ComparePassword(hash, fmt.Sprintf("%v:%v", data, utils.Cfg.EmailSettings.InviteSalt)) { c.Err = model.NewLocAppError("signupTeamComplete", "web.signup_user_complete.link_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*48 { // 48 hour c.Err = model.NewLocAppError("signupTeamComplete", "web.signup_user_complete.link_expired.app_error", nil, "") return } } page := NewHtmlTemplatePage("signup_user_complete", c.T("web.signup_user_complete.title"), c.Locale) page.Props["Email"] = props["email"] page.Props["TeamDisplayName"] = props["display_name"] page.Props["TeamName"] = props["name"] page.Props["TeamId"] = props["id"] page.Props["Data"] = data page.Props["Hash"] = hash page.Render(c, w) }
func findTeamByName(c *Context, w http.ResponseWriter, r *http.Request) { m := model.MapFromJson(r.Body) name := strings.ToLower(strings.TrimSpace(m["name"])) found := FindTeamByName(name) if found { w.Write([]byte("true")) } else { w.Write([]byte("false")) } }
func getPublicLink(c *Context, w http.ResponseWriter, r *http.Request) { if !utils.Cfg.TeamSettings.AllowPublicLink { c.Err = model.NewAppError("getPublicLink", "Public links have been disabled", "") c.Err.StatusCode = http.StatusForbidden } if !utils.IsS3Configured() { c.Err = model.NewAppError("getPublicLink", "Unable to get link. Amazon S3 not configured. ", "") c.Err.StatusCode = http.StatusNotImplemented return } props := model.MapFromJson(r.Body) filename := props["filename"] if len(filename) == 0 { c.SetInvalidParam("getPublicLink", "filename") return } matches := model.PartialUrlRegex.FindAllStringSubmatch(filename, -1) if len(matches) == 0 || len(matches[0]) < 5 { c.SetInvalidParam("getPublicLink", "filename") return } getType := matches[0][1] channelId := matches[0][2] userId := matches[0][3] filename = matches[0][4] cchan := Srv.Store.Channel().CheckPermissionsTo(c.Session.TeamId, channelId, c.Session.UserId) newProps := make(map[string]string) newProps["filename"] = filename newProps["time"] = fmt.Sprintf("%v", model.GetMillis()) data := model.MapToJson(newProps) hash := model.HashPassword(fmt.Sprintf("%v:%v", data, utils.Cfg.ServiceSettings.PublicLinkSalt)) url := fmt.Sprintf("%s/api/v1/files/%s/%s/%s/%s?d=%s&h=%s&t=%s", c.TeamUrl, getType, channelId, userId, filename, url.QueryEscape(data), url.QueryEscape(hash), c.Session.TeamId) if !c.HasPermissionsToChannel(cchan, "getPublicLink") { return } rData := make(map[string]string) rData["public_link"] = url w.Write([]byte(model.MapToJson(rData))) }
func signupTeam(c *Context, w http.ResponseWriter, r *http.Request) { if !utils.Cfg.EmailSettings.EnableSignUpWithEmail { c.Err = model.NewLocAppError("signupTeam", "api.team.signup_team.email_disabled.app_error", nil, "") c.Err.StatusCode = http.StatusNotImplemented return } m := model.MapFromJson(r.Body) email := strings.ToLower(strings.TrimSpace(m["email"])) if len(email) == 0 { c.SetInvalidParam("signupTeam", "email") return } if !isTeamCreationAllowed(c, email) { return } subjectPage := utils.NewHTMLTemplate("signup_team_subject", c.Locale) subjectPage.Props["Subject"] = c.T("api.templates.signup_team_subject", map[string]interface{}{"SiteName": utils.ClientCfg["SiteName"]}) bodyPage := utils.NewHTMLTemplate("signup_team_body", c.Locale) bodyPage.Props["SiteURL"] = c.GetSiteURL() bodyPage.Props["Title"] = c.T("api.templates.signup_team_body.title") bodyPage.Props["Button"] = c.T("api.templates.signup_team_body.button") bodyPage.Html["Info"] = template.HTML(c.T("api.templates.signup_team_body.info", map[string]interface{}{"SiteName": utils.ClientCfg["SiteName"]})) props := make(map[string]string) props["email"] = email props["time"] = fmt.Sprintf("%v", model.GetMillis()) data := model.MapToJson(props) hash := model.HashPassword(fmt.Sprintf("%v:%v", data, utils.Cfg.EmailSettings.InviteSalt)) bodyPage.Props["Link"] = fmt.Sprintf("%s/signup_team_complete/?d=%s&h=%s", c.GetSiteURL(), url.QueryEscape(data), url.QueryEscape(hash)) if err := utils.SendMail(email, subjectPage.Render(), bodyPage.Render()); err != nil { c.Err = err return } if !utils.Cfg.EmailSettings.RequireEmailVerification { m["follow_link"] = fmt.Sprintf("/signup_team_complete/?d=%s&h=%s", url.QueryEscape(data), url.QueryEscape(hash)) } w.Header().Set("Access-Control-Allow-Origin", " *") w.Write([]byte(model.MapToJson(m))) }
func updateNotifyProps(c *Context, w http.ResponseWriter, r *http.Request) { data := model.MapFromJson(r.Body) userId := data["user_id"] if len(userId) != 26 { c.SetInvalidParam("updateMarkUnreadLevel", "user_id") return } channelId := data["channel_id"] if len(channelId) != 26 { c.SetInvalidParam("updateMarkUnreadLevel", "channel_id") return } cchan := Srv.Store.Channel().CheckPermissionsTo(c.Session.TeamId, channelId, c.Session.UserId) if !c.HasPermissionsToUser(userId, "updateNotifyLevel") { return } if !c.HasPermissionsToChannel(cchan, "updateNotifyLevel") { return } result := <-Srv.Store.Channel().GetMember(channelId, userId) if result.Err != nil { c.Err = result.Err return } member := result.Data.(model.ChannelMember) // update whichever notify properties have been provided, but don't change the others if markUnread, exists := data["mark_unread"]; exists { member.NotifyProps["mark_unread"] = markUnread } if desktop, exists := data["desktop"]; exists { member.NotifyProps["desktop"] = desktop } if result := <-Srv.Store.Channel().UpdateMember(&member); result.Err != nil { c.Err = result.Err return } else { // return the updated notify properties including any unchanged ones w.Write([]byte(model.MapToJson(member.NotifyProps))) } }
func getPublicLink(c *Context, w http.ResponseWriter, r *http.Request) { if len(utils.Cfg.FileSettings.DriverName) == 0 { 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.NewLocAppError("getPublicLink", "api.file.get_public_link.disabled.app_error", nil, "") c.Err.StatusCode = http.StatusForbidden } props := model.MapFromJson(r.Body) filename := props["filename"] if len(filename) == 0 { c.SetInvalidParam("getPublicLink", "filename") return } matches := model.PartialUrlRegex.FindAllStringSubmatch(filename, -1) if len(matches) == 0 || len(matches[0]) < 4 { c.SetInvalidParam("getPublicLink", "filename") return } channelId := matches[0][1] userId := matches[0][2] filename = matches[0][3] cchan := Srv.Store.Channel().CheckPermissionsTo(c.Session.TeamId, channelId, c.Session.UserId) newProps := make(map[string]string) newProps["filename"] = filename newProps["time"] = fmt.Sprintf("%v", model.GetMillis()) data := model.MapToJson(newProps) hash := model.HashPassword(fmt.Sprintf("%v:%v", data, utils.Cfg.FileSettings.PublicLinkSalt)) url := fmt.Sprintf("%s/api/v1/files/get/%s/%s/%s?d=%s&h=%s&t=%s", c.GetSiteURL(), channelId, userId, filename, url.QueryEscape(data), url.QueryEscape(hash), c.Session.TeamId) if !c.HasPermissionsToChannel(cchan, "getPublicLink") { return } rData := make(map[string]string) rData["public_link"] = url w.Write([]byte(model.MapToJson(rData))) }