summaryrefslogtreecommitdiffstats
path: root/api4
diff options
context:
space:
mode:
authorRuzette Tanyag <ruzette@users.noreply.github.com>2017-02-08 05:00:16 -0500
committerJoram Wilander <jwawilander@gmail.com>2017-02-08 02:00:16 -0800
commit0162d8ad08815b9b833fc651c7e185eab48cbbb2 (patch)
tree384c0032d766ad4a017a8a232590709134df8462 /api4
parent5462f0119edb788428f90fc61c8651e4a8cd9ad1 (diff)
downloadchat-0162d8ad08815b9b833fc651c7e185eab48cbbb2.tar.gz
chat-0162d8ad08815b9b833fc651c7e185eab48cbbb2.tar.bz2
chat-0162d8ad08815b9b833fc651c7e185eab48cbbb2.zip
Implement GET `/users/username/{username}` endpoint for APIv4 (#5310)
* added get user by username endpoint * added get user by username unit test and driver * changed username length to 22 characters max * changed Params to UserName to Username * reorganized get user by username and get user by email formatting in model/client4
Diffstat (limited to 'api4')
-rw-r--r--api4/api.go2
-rw-r--r--api4/apitestlib.go2
-rw-r--r--api4/context.go17
-rw-r--r--api4/params.go5
-rw-r--r--api4/user.go29
-rw-r--r--api4/user_test.go64
6 files changed, 117 insertions, 2 deletions
diff --git a/api4/api.go b/api4/api.go
index a9f92c573..6c2faa96b 100644
--- a/api4/api.go
+++ b/api4/api.go
@@ -90,7 +90,7 @@ func InitApi(full bool) {
BaseRoutes.Users = BaseRoutes.ApiRoot.PathPrefix("/users").Subrouter()
BaseRoutes.User = BaseRoutes.Users.PathPrefix("/{user_id:[A-Za-z0-9]+}").Subrouter()
- BaseRoutes.UserByUsername = BaseRoutes.Users.PathPrefix("/username/{username:[A-Za-z0-9_-.]+}").Subrouter()
+ BaseRoutes.UserByUsername = BaseRoutes.Users.PathPrefix("/username/{username:[A-Za-z0-9\\_\\-\\.]+}").Subrouter()
BaseRoutes.UserByEmail = BaseRoutes.Users.PathPrefix("/email/{email}").Subrouter()
BaseRoutes.Teams = BaseRoutes.ApiRoot.PathPrefix("/teams").Subrouter()
diff --git a/api4/apitestlib.go b/api4/apitestlib.go
index 2eaed4fd0..25bfe6f75 100644
--- a/api4/apitestlib.go
+++ b/api4/apitestlib.go
@@ -247,7 +247,7 @@ func GenerateTestEmail() string {
}
func GenerateTestUsername() string {
- return "fakeuser" + model.NewId()
+ return "fakeuser" + model.NewRandomString(13)
}
func GenerateTestTeamName() string {
diff --git a/api4/context.go b/api4/context.go
index 7ad6f30b4..6a22b4103 100644
--- a/api4/context.go
+++ b/api4/context.go
@@ -359,6 +359,22 @@ func (c *Context) RequireChannelId() *Context {
return c
}
+func (c *Context) RequireUsername() *Context {
+ if c.Err != nil {
+ return c
+ }
+
+ if len(c.Params.Username) < 3 {
+ c.SetInvalidUrlParam("username")
+ }
+
+ if len(c.Params.Username) > 22 {
+ c.SetInvalidUrlParam("username")
+ }
+
+ return c
+}
+
func (c *Context) RequireEmail() *Context {
if c.Err != nil {
return c
@@ -371,3 +387,4 @@ func (c *Context) RequireEmail() *Context {
return c
}
+
diff --git a/api4/params.go b/api4/params.go
index a043919fa..4de1da401 100644
--- a/api4/params.go
+++ b/api4/params.go
@@ -26,6 +26,7 @@ type ApiParams struct {
HookId string
EmojiId string
Email string
+ Username string
Page int
PerPage int
}
@@ -71,6 +72,10 @@ func ApiParamsFromRequest(r *http.Request) *ApiParams {
params.Email = val
}
+ if val, ok := props["username"]; ok {
+ params.Username = 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 348ccf46c..d8d071cd2 100644
--- a/api4/user.go
+++ b/api4/user.go
@@ -30,6 +30,7 @@ func InitUser() {
BaseRoutes.Users.Handle("/login", ApiHandler(login)).Methods("POST")
BaseRoutes.Users.Handle("/logout", ApiHandler(logout)).Methods("POST")
+ BaseRoutes.UserByUsername.Handle("", ApiSessionRequired(getUserByUsername)).Methods("GET")
BaseRoutes.UserByEmail.Handle("", ApiSessionRequired(getUserByEmail)).Methods("GET")
}
@@ -93,6 +94,34 @@ func getUser(c *Context, w http.ResponseWriter, r *http.Request) {
}
}
+func getUserByUsername(c *Context, w http.ResponseWriter, r *http.Request) {
+ c.RequireUsername()
+ if c.Err != nil {
+ return
+ }
+
+ // No permission check required
+
+ var user *model.User
+ var err *model.AppError
+
+ if user, err = app.GetUserByUsername(c.Params.Username); 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 getUserByEmail(c *Context, w http.ResponseWriter, r *http.Request) {
c.RequireEmail()
if c.Err != nil {
diff --git a/api4/user_test.go b/api4/user_test.go
index 37f251c6d..82c7f921d 100644
--- a/api4/user_test.go
+++ b/api4/user_test.go
@@ -133,6 +133,70 @@ func TestGetUser(t *testing.T) {
}
}
+func TestGetUserByUsername(t *testing.T) {
+ th := Setup().InitBasic().InitSystemAdmin()
+ defer TearDown()
+ Client := th.Client
+
+ user := th.BasicUser
+
+ ruser, resp := Client.GetUserByUsername(user.Username, "")
+ CheckNoError(t, resp)
+ CheckUserSanitization(t, ruser)
+
+ if ruser.Email != user.Email {
+ t.Fatal("emails did not match")
+ }
+
+ ruser, resp = Client.GetUserByUsername(user.Username, resp.Etag)
+ CheckEtag(t, ruser, resp)
+
+ _, resp = Client.GetUserByUsername(GenerateTestUsername(), "")
+ CheckNotFoundStatus(t, resp)
+
+ _, resp = Client.GetUserByUsername(model.NewRandomString(25), "")
+ CheckBadRequestStatus(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.GetUserByUsername(user.Username, "")
+ 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.GetUserByUsername(user.Username, "")
+ CheckUnauthorizedStatus(t, resp)
+
+ // System admins should ignore privacy settings
+ ruser, resp = th.SystemAdminClient.GetUserByUsername(user.Username, 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 TestGetUserByEmail(t *testing.T) {
th := Setup().InitBasic().InitSystemAdmin()
defer TearDown()