diff options
Diffstat (limited to 'api')
-rw-r--r-- | api/export.go | 2 | ||||
-rw-r--r-- | api/team.go | 48 | ||||
-rw-r--r-- | api/team_test.go | 33 | ||||
-rw-r--r-- | api/user.go | 74 | ||||
-rw-r--r-- | api/user_test.go | 21 |
5 files changed, 151 insertions, 27 deletions
diff --git a/api/export.go b/api/export.go index 6d7698282..c6bc626f9 100644 --- a/api/export.go +++ b/api/export.go @@ -87,7 +87,7 @@ func ExportTeams(writer ExportWriter, options *ExportOptions) *model.AppError { // Get the teams var teams []*model.Team if len(options.TeamsToExport) == 0 { - if result := <-Srv.Store.Team().GetForExport(); result.Err != nil { + if result := <-Srv.Store.Team().GetAll(); result.Err != nil { return result.Err } else { teams = result.Data.([]*model.Team) diff --git a/api/team.go b/api/team.go index c9d2412d3..d59b2b484 100644 --- a/api/team.go +++ b/api/team.go @@ -25,6 +25,7 @@ func InitTeam(r *mux.Router) { sr.Handle("/create_from_signup", ApiAppHandler(createTeamFromSignup)).Methods("POST") sr.Handle("/create_with_sso/{service:[A-Za-z]+}", ApiAppHandler(createTeamFromSSO)).Methods("POST") sr.Handle("/signup", ApiAppHandler(signupTeam)).Methods("POST") + sr.Handle("/all", ApiUserRequired(getAll)).Methods("GET") sr.Handle("/find_team_by_name", ApiAppHandler(findTeamByName)).Methods("POST") sr.Handle("/find_teams", ApiAppHandler(findTeams)).Methods("POST") sr.Handle("/email_teams", ApiAppHandler(emailTeams)).Methods("POST") @@ -302,6 +303,53 @@ func isTreamCreationAllowed(c *Context, email string) bool { return true } +func getAll(c *Context, w http.ResponseWriter, r *http.Request) { + if !c.HasSystemAdminPermissions("getLogs") { + return + } + + if result := <-Srv.Store.Team().GetAll(); result.Err != nil { + c.Err = result.Err + return + } else { + teams := result.Data.([]*model.Team) + m := make(map[string]*model.Team) + for _, v := range teams { + m[v.Id] = v + } + + w.Write([]byte(model.TeamMapToJson(m))) + } +} + +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 findTeamByName(c *Context, w http.ResponseWriter, r *http.Request) { m := model.MapFromJson(r.Body) diff --git a/api/team_test.go b/api/team_test.go index cd39dacfe..e2a7cf430 100644 --- a/api/team_test.go +++ b/api/team_test.go @@ -132,6 +132,39 @@ func TestFindTeamByEmail(t *testing.T) { } } +func TestGetAllTeams(t *testing.T) { + Setup() + + team := &model.Team{DisplayName: "Name", Name: "z-z-" + model.NewId() + "a", Email: "test@nowhere.com", Type: model.TEAM_OPEN} + team = Client.Must(Client.CreateTeam(team)).Data.(*model.Team) + + user := &model.User{TeamId: team.Id, Email: model.NewId() + "corey@test.com", Nickname: "Corey Hulen", Password: "pwd"} + user = Client.Must(Client.CreateUser(user, "")).Data.(*model.User) + store.Must(Srv.Store.User().VerifyEmail(user.Id)) + + Client.LoginByEmail(team.Name, user.Email, "pwd") + + if _, err := Client.GetAllTeams(); err == nil { + t.Fatal("you shouldn't have permissions") + } + + c := &Context{} + c.RequestId = model.NewId() + c.IpAddress = "cmd_line" + UpdateRoles(c, user, model.ROLE_SYSTEM_ADMIN) + + Client.LoginByEmail(team.Name, user.Email, "pwd") + + if r1, err := Client.GetAllTeams(); err != nil { + t.Fatal(err) + } else { + teams := r1.Data.(map[string]*model.Team) + if teams[team.Id].Name != team.Name { + t.Fatal() + } + } +} + /* XXXXXX investigate and fix failing test diff --git a/api/user.go b/api/user.go index d61afb027..348475e38 100644 --- a/api/user.go +++ b/api/user.go @@ -51,6 +51,7 @@ func InitUser(r *mux.Router) { sr.Handle("/me", ApiAppHandler(getMe)).Methods("GET") sr.Handle("/status", ApiUserRequiredActivity(getStatuses, false)).Methods("GET") sr.Handle("/profiles", ApiUserRequired(getProfiles)).Methods("GET") + sr.Handle("/profiles/{id:[A-Za-z0-9]+}", ApiUserRequired(getProfiles)).Methods("GET") sr.Handle("/{id:[A-Za-z0-9]+}", ApiUserRequired(getUser)).Methods("GET") sr.Handle("/{id:[A-Za-z0-9]+}/sessions", ApiUserRequired(getSessions)).Methods("GET") sr.Handle("/{id:[A-Za-z0-9]+}/audits", ApiUserRequired(getAudits)).Methods("GET") @@ -553,13 +554,26 @@ func getUser(c *Context, w http.ResponseWriter, r *http.Request) { } func getProfiles(c *Context, w http.ResponseWriter, r *http.Request) { + params := mux.Vars(r) + id, ok := params["id"] + if ok { + // You must be system admin to access another team + if id != c.Session.TeamId { + if !c.HasSystemAdminPermissions("getProfiles") { + return + } + } - etag := (<-Srv.Store.User().GetEtagForProfiles(c.Session.TeamId)).Data.(string) + } else { + id = c.Session.TeamId + } + + etag := (<-Srv.Store.User().GetEtagForProfiles(id)).Data.(string) if HandleEtag(etag, w, r) { return } - if result := <-Srv.Store.User().GetProfiles(c.Session.TeamId); result.Err != nil { + if result := <-Srv.Store.User().GetProfiles(id); result.Err != nil { c.Err = result.Err return } else { @@ -1158,29 +1172,35 @@ func resetPassword(c *Context, w http.ResponseWriter, r *http.Request) { return } - hash := props["hash"] - if len(hash) == 0 { - c.SetInvalidParam("resetPassword", "hash") + name := props["name"] + if len(name) == 0 { + c.SetInvalidParam("resetPassword", "name") return } - data := model.MapFromJson(strings.NewReader(props["data"])) + userId := props["user_id"] + hash := props["hash"] + timeStr := "" - userId := data["user_id"] - if len(userId) != 26 { - c.SetInvalidParam("resetPassword", "data:user_id") - return - } + if !c.IsSystemAdmin() { + if len(hash) == 0 { + c.SetInvalidParam("resetPassword", "hash") + return + } - timeStr := data["time"] - if len(timeStr) == 0 { - c.SetInvalidParam("resetPassword", "data:time") - return + data := model.MapFromJson(strings.NewReader(props["data"])) + + userId = data["user_id"] + + timeStr = data["time"] + if len(timeStr) == 0 { + c.SetInvalidParam("resetPassword", "data:time") + return + } } - name := props["name"] - if len(name) == 0 { - c.SetInvalidParam("resetPassword", "name") + if len(userId) != 26 { + c.SetInvalidParam("resetPassword", "user_id") return } @@ -1208,15 +1228,17 @@ func resetPassword(c *Context, w http.ResponseWriter, r *http.Request) { return } - 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", "") - 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", "") + 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", "") - 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", "") + return + } } if result := <-Srv.Store.User().UpdatePassword(userId, model.HashPassword(newPassword)); result.Err != nil { diff --git a/api/user_test.go b/api/user_test.go index 34eefce59..c2dca752c 100644 --- a/api/user_test.go +++ b/api/user_test.go @@ -228,6 +228,13 @@ func TestGetUser(t *testing.T) { ruser2, _ := Client.CreateUser(&user2, "") store.Must(Srv.Store.User().VerifyEmail(ruser2.Data.(*model.User).Id)) + team2 := model.Team{DisplayName: "Name", Name: "z-z-" + model.NewId() + "a", Email: "test@nowhere.com", Type: model.TEAM_OPEN} + rteam2, _ := Client.CreateTeam(&team2) + + user3 := model.User{TeamId: rteam2.Data.(*model.Team).Id, Email: strings.ToLower(model.NewId()) + "corey@test.com", Nickname: "Corey Hulen", Password: "pwd"} + ruser3, _ := Client.CreateUser(&user3, "") + store.Must(Srv.Store.User().VerifyEmail(ruser3.Data.(*model.User).Id)) + Client.LoginByEmail(team.Name, user.Email, user.Password) rId := ruser.Data.(*model.User).Id @@ -276,13 +283,27 @@ func TestGetUser(t *testing.T) { t.Log(cache_result.Data) t.Fatal("cache should be empty") } + } + if _, err := Client.GetProfiles(rteam2.Data.(*model.Team).Id, ""); err == nil { + t.Fatal("shouldn't have access") } Client.AuthToken = "" if _, err := Client.GetUser(ruser2.Data.(*model.User).Id, ""); err == nil { t.Fatal("shouldn't have accss") } + + c := &Context{} + c.RequestId = model.NewId() + c.IpAddress = "cmd_line" + UpdateRoles(c, ruser.Data.(*model.User), model.ROLE_SYSTEM_ADMIN) + + Client.LoginByEmail(team.Name, user.Email, "pwd") + + if _, err := Client.GetProfiles(rteam2.Data.(*model.Team).Id, ""); err != nil { + t.Fatal(err) + } } func TestGetAudits(t *testing.T) { |