Implement GET /users/email/{email} endpoint for APIv4 (#5309)

* added get user by email endpoint for APIv4

* added get user by email endpoint unit test and driver

* removed the appended return of user ids on logout

* Added RequireEmail to validate user email. Also updated the get user by email endpoint and unit test
Этот коммит содержится в:
Ruzette Tanyag
2017-02-07 11:54:07 -05:00
коммит произвёл Christopher Speller
родитель 5cc30fa061
Коммит d91fea6518
6 изменённых файлов: 134 добавлений и 4 удалений

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

@@ -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
}

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

@@ -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 {

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

@@ -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) {

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

@@ -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

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

@@ -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

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

@@ -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)