support pagination

This commit is contained in:
Wenkai Yin 2017-06-12 17:49:18 +08:00
parent 83be92f1f0
commit 539c0375a1
8 changed files with 104 additions and 43 deletions

View File

@ -491,6 +491,23 @@ paths:
type: string
required: false
description: Username for filtering results.
- name: email
in: query
type: string
required: false
description: Email for filtering results.
- name: page
in: query
type: integer
format: int32
required: false
description: The page nubmer, default is 1.
- name: page_size
in: query
type: integer
format: int32
required: false
description: The size of per page.
tags:
- Products
responses:

View File

@ -407,14 +407,14 @@ func TestGetUser(t *testing.T) {
}
func TestListUsers(t *testing.T) {
users, err := ListUsers(models.User{})
users, err := ListUsers(nil)
if err != nil {
t.Errorf("Error occurred in ListUsers: %v", err)
}
if len(users) != 1 {
if len(users) != 2 {
t.Errorf("Expect one user in list, but the acutal length is %d, the list: %+v", len(users), users)
}
users2, err := ListUsers(models.User{Username: username})
users2, err := ListUsers(&models.UserQuery{Username: username})
if len(users2) != 1 {
t.Errorf("Expect one user in list, but the acutal length is %d, the list: %+v", len(users), users)
}

View File

@ -127,6 +127,10 @@ func GetTotalOfRepositories(name string) (int64, error) {
// GetTotalOfRepositoriesByProject ...
func GetTotalOfRepositoriesByProject(projectIDs []int64, name string) (int64, error) {
if len(projectIDs) == 0 {
return 0, nil
}
qs := GetOrmer().QueryTable(&models.RepoRecord{}).
Filter("project_id__in", projectIDs)

View File

@ -19,6 +19,8 @@ import (
"errors"
"fmt"
"github.com/astaxie/beego/orm"
"github.com/vmware/harbor/src/common/models"
"github.com/vmware/harbor/src/common/utils"
@ -92,24 +94,36 @@ func LoginByDb(auth models.AuthModel) (*models.User, error) {
return &user, nil
}
// GetTotalOfUsers ...
func GetTotalOfUsers(query *models.UserQuery) (int64, error) {
return userQueryConditions(query).Count()
}
// ListUsers lists all users according to different conditions.
func ListUsers(query models.User) ([]models.User, error) {
o := GetOrmer()
u := []models.User{}
sql := `select user_id, username, email, realname, comment, reset_uuid, salt,
sysadmin_flag, creation_time, update_time
from user u
where u.deleted = 0 and u.user_id != 1 `
func ListUsers(query *models.UserQuery) ([]models.User, error) {
users := []models.User{}
_, err := userQueryConditions(query).
OrderBy("username").
All(&users)
return users, err
}
queryParam := make([]interface{}, 1)
if query.Username != "" {
sql += ` and username like ? `
queryParam = append(queryParam, "%"+escape(query.Username)+"%")
func userQueryConditions(query *models.UserQuery) orm.QuerySeter {
qs := GetOrmer().QueryTable(&models.User{}).Filter("deleted", 0)
if query == nil {
return qs
}
sql += ` order by user_id desc `
_, err := o.Raw(sql, queryParam).QueryRows(&u)
return u, err
if len(query.Username) > 0 {
qs = qs.Filter("username__contains", query.Username)
}
if len(query.Email) > 0 {
qs = qs.Filter("email__contains", query.Email)
}
return qs
}
// ToggleUserAdminRole gives a user admin role.

View File

@ -27,10 +27,10 @@ type User struct {
Realname string `orm:"column(realname)" json:"realname"`
Comment string `orm:"column(comment)" json:"comment"`
Deleted int `orm:"column(deleted)" json:"deleted"`
Rolename string `json:"role_name"`
Rolename string `orm:"-" json:"role_name"`
//if this field is named as "RoleID", beego orm can not map role_id
//to it.
Role int `json:"role_id"`
Role int `orm:"-" json:"role_id"`
// RoleList []Role `json:"role_list"`
HasAdminRole int `orm:"column(sysadmin_flag)" json:"has_admin_role"`
ResetUUID string `orm:"column(reset_uuid)" json:"reset_uuid"`
@ -38,3 +38,10 @@ type User struct {
CreationTime time.Time `orm:"creation_time" json:"creation_time"`
UpdateTime time.Time `orm:"update_time" json:"update_time"`
}
// UserQuery ...
type UserQuery struct {
Username string
Email string
Pagination *Pagination
}

View File

@ -92,7 +92,8 @@ func init() {
beego.Router("/api/search/", &SearchAPI{})
beego.Router("/api/projects/", &ProjectAPI{}, "get:List;post:Post;head:Head")
beego.Router("/api/projects/:id", &ProjectAPI{}, "delete:Delete;get:Get")
beego.Router("/api/users/?:id", &UserAPI{})
beego.Router("/api/users/:id", &UserAPI{}, "get:Get")
beego.Router("/api/users", &UserAPI{}, "get:List;post:Post;delete:Delete;put:Put")
beego.Router("/api/users/:id([0-9]+)/password", &UserAPI{}, "put:ChangePassword")
beego.Router("/api/users/:id/sysadmin", &UserAPI{}, "put:ToggleUserAdminRole")
beego.Router("/api/projects/:id/publicity", &ProjectAPI{}, "put:ToggleProjectPublic")

View File

@ -106,26 +106,7 @@ func (ua *UserAPI) Prepare() {
// Get ...
func (ua *UserAPI) Get() {
if ua.userID == 0 { //list users
if !ua.IsAdmin {
log.Errorf("Current user, id: %d does not have admin role, can not list users", ua.currentUserID)
ua.RenderError(http.StatusForbidden, "User does not have admin role")
return
}
username := ua.GetString("username")
userQuery := models.User{}
if len(username) > 0 {
userQuery.Username = username
}
userList, err := dao.ListUsers(userQuery)
if err != nil {
log.Errorf("Failed to get data from database, error: %v", err)
ua.RenderError(http.StatusInternalServerError, "Failed to query from database")
return
}
ua.Data["json"] = userList
} else if ua.userID == ua.currentUserID || ua.IsAdmin {
if ua.userID == ua.currentUserID || ua.IsAdmin {
userQuery := models.User{UserID: ua.userID}
u, err := dao.GetUser(userQuery)
if err != nil {
@ -133,11 +114,47 @@ func (ua *UserAPI) Get() {
ua.CustomAbort(http.StatusInternalServerError, "Internal error.")
}
ua.Data["json"] = u
} else {
log.Errorf("Current user, id: %d does not have admin role, can not view other user's detail", ua.currentUserID)
ua.ServeJSON()
return
}
log.Errorf("Current user, id: %d does not have admin role, can not view other user's detail", ua.currentUserID)
ua.RenderError(http.StatusForbidden, "User does not have admin role")
return
}
// List ...
func (ua *UserAPI) List() {
if !ua.IsAdmin {
log.Errorf("Current user, id: %d does not have admin role, can not list users", ua.currentUserID)
ua.RenderError(http.StatusForbidden, "User does not have admin role")
return
}
page, size := ua.GetPaginationParams()
query := &models.UserQuery{
Username: ua.GetString("username"),
Email: ua.GetString("email"),
Pagination: &models.Pagination{
Page: page,
Size: size,
},
}
total, err := dao.GetTotalOfUsers(query)
if err != nil {
ua.HandleInternalServerError(fmt.Sprintf("failed to get total of users: %v", err))
return
}
users, err := dao.ListUsers(query)
if err != nil {
ua.HandleInternalServerError(fmt.Sprintf("failed to get users: %v", err))
return
}
ua.SetPaginationHeader(total, page, size)
ua.Data["json"] = users
ua.ServeJSON()
}

View File

@ -68,7 +68,8 @@ func initRouters() {
beego.Router("/api/projects/:id([0-9]+)/publicity", &api.ProjectAPI{}, "put:ToggleProjectPublic")
beego.Router("/api/projects/:id([0-9]+)/logs", &api.ProjectAPI{}, "get:Logs")
beego.Router("/api/statistics", &api.StatisticAPI{})
beego.Router("/api/users/?:id", &api.UserAPI{})
beego.Router("/api/users/:id", &api.UserAPI{}, "get:Get")
beego.Router("/api/users", &api.UserAPI{}, "get:List;post:Post;delete:Delete;put:Put")
beego.Router("/api/users/:id([0-9]+)/password", &api.UserAPI{}, "put:ChangePassword")
beego.Router("/api/internal/syncregistry", &api.InternalAPI{}, "post:SyncRegistry")
beego.Router("/api/repositories", &api.RepositoryAPI{}, "get:Get")