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
Этот коммит содержится в:
коммит произвёл
Christopher Speller
родитель
5cc30fa061
Коммит
d91fea6518
@@ -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 {
|
||||
|
||||
34
api4/user.go
34
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) {
|
||||
|
||||
@@ -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)
|
||||
|
||||
Ссылка в новой задаче
Block a user