summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--api4/context.go13
-rw-r--r--api4/params.go5
-rw-r--r--api4/user.go34
-rw-r--r--api4/user_test.go65
-rw-r--r--app/user.go7
-rw-r--r--model/client4.go14
6 files changed, 134 insertions, 4 deletions
diff --git a/api4/context.go b/api4/context.go
index 1a3011795..7ad6f30b4 100644
--- a/api4/context.go
+++ b/api4/context.go
@@ -358,3 +358,16 @@ func (c *Context) RequireChannelId() *Context {
}
return c
}
+
+func (c *Context) RequireEmail() *Context {
+ if c.Err != nil {
+ return c
+ }
+
+ pos := strings.Index(c.Params.Email, "@")
+ if pos < 0 {
+ c.SetInvalidUrlParam("email")
+ }
+
+ return c
+}
diff --git a/api4/params.go b/api4/params.go
index 1c0c153ea..a043919fa 100644
--- a/api4/params.go
+++ b/api4/params.go
@@ -25,6 +25,7 @@ type ApiParams struct {
CommandId string
HookId string
EmojiId string
+ Email string
Page int
PerPage int
}
@@ -66,6 +67,10 @@ func ApiParamsFromRequest(r *http.Request) *ApiParams {
params.EmojiId = val
}
+ if val, ok := props["email"]; ok {
+ params.Email = val
+ }
+
if val, err := strconv.Atoi(r.URL.Query().Get("page")); err != nil {
params.Page = PAGE_DEFAULT
} else {
diff --git a/api4/user.go b/api4/user.go
index 14067bdf5..cf9bb4ead 100644
--- a/api4/user.go
+++ b/api4/user.go
@@ -27,6 +27,8 @@ func InitUser() {
BaseRoutes.Users.Handle("/login", ApiHandler(login)).Methods("POST")
BaseRoutes.Users.Handle("/logout", ApiHandler(logout)).Methods("POST")
+ BaseRoutes.UserByEmail.Handle("", ApiSessionRequired(getUserByEmail)).Methods("GET")
+
}
func createUser(c *Context, w http.ResponseWriter, r *http.Request) {
@@ -88,6 +90,34 @@ func getUser(c *Context, w http.ResponseWriter, r *http.Request) {
}
}
+func getUserByEmail(c *Context, w http.ResponseWriter, r *http.Request) {
+ c.RequireEmail()
+ if c.Err != nil {
+ return
+ }
+
+ // No permission check required
+
+ var user *model.User
+ var err *model.AppError
+
+ if user, err = app.GetUserByEmail(c.Params.Email); err != nil {
+ c.Err = err
+ return
+ }
+
+ etag := user.Etag(utils.Cfg.PrivacySettings.ShowFullName, utils.Cfg.PrivacySettings.ShowEmailAddress)
+
+ if HandleEtag(etag, "Get User", w, r) {
+ return
+ } else {
+ app.SanitizeProfile(user, c.IsSystemAdmin())
+ w.Header().Set(model.HEADER_ETAG_SERVER, etag)
+ w.Write([]byte(user.ToJson()))
+ return
+ }
+}
+
func getUsers(c *Context, w http.ResponseWriter, r *http.Request) {
inTeamId := r.URL.Query().Get("in_team")
inChannelId := r.URL.Query().Get("in_channel")
@@ -292,9 +322,7 @@ func logout(c *Context, w http.ResponseWriter, r *http.Request) {
data["user_id"] = c.Session.UserId
Logout(c, w, r)
- if c.Err == nil {
- w.Write([]byte(model.MapToJson(data)))
- }
+
}
func Logout(c *Context, w http.ResponseWriter, r *http.Request) {
diff --git a/api4/user_test.go b/api4/user_test.go
index 40f6b4117..dc8a82310 100644
--- a/api4/user_test.go
+++ b/api4/user_test.go
@@ -131,6 +131,71 @@ func TestGetUser(t *testing.T) {
}
}
+func TestGetUserByEmail(t *testing.T) {
+ th := Setup().InitBasic().InitSystemAdmin()
+ defer TearDown()
+ Client := th.Client
+
+ user := th.CreateUser()
+
+ ruser, resp := Client.GetUserByEmail(user.Email, "")
+ CheckNoError(t, resp)
+ CheckUserSanitization(t, ruser)
+
+ if ruser.Email != user.Email {
+ t.Fatal("emails did not match")
+ }
+
+ ruser, resp = Client.GetUserByEmail(user.Email, resp.Etag)
+ CheckEtag(t, ruser, resp)
+
+
+ _, resp = Client.GetUserByEmail(GenerateTestUsername(), "")
+ CheckBadRequestStatus(t, resp)
+
+ _, resp = Client.GetUserByEmail(GenerateTestEmail(), "")
+ CheckNotFoundStatus(t, resp)
+
+ // Check against privacy config settings
+ emailPrivacy := utils.Cfg.PrivacySettings.ShowEmailAddress
+ namePrivacy := utils.Cfg.PrivacySettings.ShowFullName
+ defer func() {
+ utils.Cfg.PrivacySettings.ShowEmailAddress = emailPrivacy
+ utils.Cfg.PrivacySettings.ShowFullName = namePrivacy
+ }()
+ utils.Cfg.PrivacySettings.ShowEmailAddress = false
+ utils.Cfg.PrivacySettings.ShowFullName = false
+
+ ruser, resp = Client.GetUserByEmail(user.Email, "")
+ CheckNoError(t, resp)
+
+ if ruser.Email != "" {
+ t.Fatal("email should be blank")
+ }
+ if ruser.FirstName != "" {
+ t.Fatal("first name should be blank")
+ }
+ if ruser.LastName != "" {
+ t.Fatal("last name should be blank")
+ }
+
+ Client.Logout()
+ _, resp = Client.GetUserByEmail(user.Email, "")
+ CheckUnauthorizedStatus(t, resp)
+
+ // System admins should ignore privacy settings
+ ruser, resp = th.SystemAdminClient.GetUserByEmail(user.Email, resp.Etag)
+ if ruser.Email == "" {
+ t.Fatal("email should not be blank")
+ }
+ if ruser.FirstName == "" {
+ t.Fatal("first name should not be blank")
+ }
+ if ruser.LastName == "" {
+ t.Fatal("last name should not be blank")
+ }
+}
+
func TestGetUsersByIds(t *testing.T) {
th := Setup().InitBasic()
Client := th.Client
diff --git a/app/user.go b/app/user.go
index bc809cfaa..c302db511 100644
--- a/app/user.go
+++ b/app/user.go
@@ -331,7 +331,12 @@ func GetUserByUsername(username string) (*model.User, *model.AppError) {
}
func GetUserByEmail(email string) (*model.User, *model.AppError) {
- if result := <-Srv.Store.User().GetByEmail(email); result.Err != nil {
+
+ if result := <-Srv.Store.User().GetByEmail(email); result.Err != nil && result.Err.Id == "store.sql_user.missing_account.const"{
+ result.Err.StatusCode = http.StatusNotFound
+ return nil, result.Err
+ } else if result.Err != nil {
+ result.Err.StatusCode = http.StatusBadRequest
return nil, result.Err
} else {
return result.Data.(*model.User), nil
diff --git a/model/client4.go b/model/client4.go
index 1bdb7e55e..42b96a730 100644
--- a/model/client4.go
+++ b/model/client4.go
@@ -56,6 +56,10 @@ func (c *Client4) GetUserRoute(userId string) string {
return fmt.Sprintf(c.GetUsersRoute()+"/%v", userId)
}
+func (c *Client4) GetUserByEmailRoute(email string) string {
+ return fmt.Sprintf(c.GetUsersRoute()+"/email/%v", email)
+}
+
func (c *Client4) GetTeamsRoute() string {
return fmt.Sprintf("/teams")
}
@@ -210,6 +214,16 @@ func (c *Client4) GetUser(userId, etag string) (*User, *Response) {
}
}
+// GetUserByEmail returns a user based on the provided user email string.
+func (c *Client4) GetUserByEmail(email, etag string) (*User, *Response) {
+ if r, err := c.DoApiGet(c.GetUserByEmailRoute(email), etag); err != nil {
+ return nil, &Response{StatusCode: r.StatusCode, Error: err}
+ } else {
+ defer closeBody(r)
+ return UserFromJson(r.Body), BuildResponse(r)
+ }
+}
+
// GetUsers returns a page of users on the system. Page counting starts at 0.
func (c *Client4) GetUsers(page int, perPage int, etag string) ([]*User, *Response) {
query := fmt.Sprintf("?page=%v&per_page=%v", page, perPage)