Merge pull request #2386 from ywk253100/170525_log_pagination

Support pagination in GET recent logs API
This commit is contained in:
Wenkai Yin 2017-06-05 17:15:15 +08:00 committed by GitHub
commit 0679796528
17 changed files with 193 additions and 326 deletions

View File

@ -861,24 +861,18 @@ paths:
description: |
This endpoint let user see the recent operation logs of the projects which he is member of
parameters:
- name: lines
- name: page
in: query
type: integer
format: int32
required: false
description: The number of logs to be shown, default is 10 if lines, start_time, end_time are not provided.
- name: start_time
description: The page nubmer, default is 1.
- name: page_size
in: query
type: integer
format: int64
format: int32
required: false
description: The start time of logs to be shown in unix timestap
- name: end_time
in: query
type: integer
format: int64
required: false
description: The end time of logs to be shown in unix timestap
description: The size of per page, default is 10, maximum is 100.
tags:
- Products
responses:
@ -889,7 +883,7 @@ paths:
items:
$ref: '#/definitions/AccessLog'
400:
description: Bad request because of invalid parameter of lines or start_time or end_time.
description: Bad request because of invalid parameters.
401:
description: User need to login first.
500:

View File

@ -15,8 +15,7 @@
package dao
import (
"strings"
"github.com/astaxie/beego/orm"
"github.com/vmware/harbor/src/common/models"
"github.com/vmware/harbor/src/common/utils/log"
)
@ -29,155 +28,61 @@ func AddAccessLog(accessLog models.AccessLog) error {
}
// GetTotalOfAccessLogs ...
func GetTotalOfAccessLogs(query models.AccessLog) (int64, error) {
o := GetOrmer()
queryParam := []interface{}{}
sql := `select count(*) from access_log al
where al.project_id = ?`
queryParam = append(queryParam, query.ProjectID)
sql += genFilterClauses(query, &queryParam)
var total int64
if err := o.Raw(sql, queryParam).QueryRow(&total); err != nil {
return 0, err
}
return total, nil
func GetTotalOfAccessLogs(query *models.LogQueryParam) (int64, error) {
return logQueryConditions(query).Count()
}
//GetAccessLogs gets access logs according to different conditions
func GetAccessLogs(query models.AccessLog, limit, offset int64) ([]models.AccessLog, error) {
o := GetOrmer()
func GetAccessLogs(query *models.LogQueryParam) ([]models.AccessLog, error) {
qs := logQueryConditions(query).OrderBy("-op_time")
queryParam := []interface{}{}
sql := `select al.log_id, al.username, al.repo_name,
al.repo_tag, al.operation, al.op_time
from access_log al
where al.project_id = ? `
queryParam = append(queryParam, query.ProjectID)
if query != nil && query.Pagination != nil {
size := query.Pagination.Size
if size > 0 {
qs = qs.Limit(size)
sql += genFilterClauses(query, &queryParam)
sql += ` order by al.op_time desc `
sql = paginateForRawSQL(sql, limit, offset)
logs := []models.AccessLog{}
_, err := o.Raw(sql, queryParam).QueryRows(&logs)
if err != nil {
return logs, err
}
return logs, nil
}
func genFilterClauses(query models.AccessLog, queryParam *[]interface{}) string {
sql := ""
if query.Username != "" {
sql += ` and al.username like ? `
*queryParam = append(*queryParam, "%"+escape(query.Username)+"%")
}
if query.Operation != "" {
sql += ` and al.operation = ? `
*queryParam = append(*queryParam, query.Operation)
}
if query.RepoName != "" {
sql += ` and al.repo_name = ? `
*queryParam = append(*queryParam, query.RepoName)
}
if query.RepoTag != "" {
sql += ` and al.repo_tag = ? `
*queryParam = append(*queryParam, query.RepoTag)
}
if query.Keywords != "" {
sql += ` and al.operation in ( `
keywordList := strings.Split(query.Keywords, "/")
num := len(keywordList)
for i := 0; i < num; i++ {
if keywordList[i] != "" {
if i == num-1 {
sql += `?)`
} else {
sql += `?,`
}
*queryParam = append(*queryParam, keywordList[i])
page := query.Pagination.Page
if page > 0 {
qs = qs.Offset((page - 1) * size)
}
}
}
if query.BeginTimestamp > 0 {
sql += ` and al.op_time >= ? `
*queryParam = append(*queryParam, query.BeginTime)
}
if query.EndTimestamp > 0 {
sql += ` and al.op_time <= ? `
*queryParam = append(*queryParam, query.EndTime)
}
return sql
logs := []models.AccessLog{}
_, err := qs.All(&logs)
return logs, err
}
//GetRecentLogs returns recent logs according to parameters
func GetRecentLogs(username string, linesNum int, startTime, endTime string) ([]models.AccessLog, error) {
logs := []models.AccessLog{}
func logQueryConditions(query *models.LogQueryParam) orm.QuerySeter {
qs := GetOrmer().QueryTable(&models.AccessLog{})
isAdmin, err := IsAdminRole(username)
if err != nil {
return logs, err
if query == nil {
return qs
}
queryParam := []interface{}{}
sql := `select log_id, username, project_id, repo_name, repo_tag, GUID, operation, op_time
from access_log `
hasWhere := false
if !isAdmin {
sql += ` where project_id in
(select distinct project_id
from project_member pm
join user u
on pm.user_id = u.user_id
where u.username = ?) `
queryParam = append(queryParam, username)
hasWhere = true
if len(query.ProjectIDs) > 0 {
qs = qs.Filter("project_id__in", query.ProjectIDs)
}
if len(query.Username) != 0 {
qs = qs.Filter("username__contains", query.Username)
}
if len(query.Repository) != 0 {
qs = qs.Filter("repo_name", query.Repository)
}
if len(query.Tag) != 0 {
qs = qs.Filter("repo_tag", query.Tag)
}
if len(query.Operations) > 0 {
qs = qs.Filter("operation__in", query.Operations)
}
if query.BeginTime != nil {
qs = qs.Filter("op_time__gte", query.BeginTime)
}
if query.EndTime != nil {
qs = qs.Filter("op_time__lte", query.EndTime)
}
if startTime != "" {
if hasWhere {
sql += " and op_time >= ?"
} else {
sql += " where op_time >= ?"
hasWhere = true
}
queryParam = append(queryParam, startTime)
}
if endTime != "" {
if hasWhere {
sql += " and op_time <= ?"
} else {
sql += " where op_time <= ?"
hasWhere = true
}
queryParam = append(queryParam, endTime)
}
sql += " order by op_time desc"
if linesNum != 0 {
sql += " limit ?"
queryParam = append(queryParam, linesNum)
}
_, err = GetOrmer().Raw(sql, queryParam).QueryRows(&logs)
if err != nil {
return logs, err
}
return logs, nil
return qs
}
// CountPull ...

View File

@ -570,11 +570,11 @@ func TestGetAccessLog(t *testing.T) {
t.Errorf("failed to add access log: %v", err)
}
queryAccessLog := models.AccessLog{
Username: currentUser.Username,
ProjectID: currentProject.ProjectID,
query := &models.LogQueryParam{
Username: currentUser.Username,
ProjectIDs: []int64{currentProject.ProjectID},
}
accessLogs, err := GetAccessLogs(queryAccessLog, 1000, 0)
accessLogs, err := GetAccessLogs(query)
if err != nil {
t.Errorf("Error occurred in GetAccessLog: %v", err)
}
@ -587,11 +587,11 @@ func TestGetAccessLog(t *testing.T) {
}
func TestGetTotalOfAccessLogs(t *testing.T) {
queryAccessLog := models.AccessLog{
Username: currentUser.Username,
ProjectID: currentProject.ProjectID,
query := &models.LogQueryParam{
Username: currentUser.Username,
ProjectIDs: []int64{currentProject.ProjectID},
}
total, err := GetTotalOfAccessLogs(queryAccessLog)
total, err := GetTotalOfAccessLogs(query)
if err != nil {
t.Fatalf("failed to get total of access log: %v", err)
}
@ -617,7 +617,15 @@ func TestAddAccessLog(t *testing.T) {
if err != nil {
t.Errorf("Error occurred in AddAccessLog: %v", err)
}
accessLogList, err = GetAccessLogs(accessLog, 1000, 0)
query := &models.LogQueryParam{
Username: accessLog.Username,
ProjectIDs: []int64{accessLog.ProjectID},
Repository: accessLog.RepoName,
Tag: accessLog.RepoTag,
Operations: []string{accessLog.Operation},
}
accessLogList, err = GetAccessLogs(query)
if err != nil {
t.Errorf("Error occurred in GetAccessLog: %v", err)
}
@ -819,7 +827,7 @@ func TestGetProjects(t *testing.T) {
func TestGetPublicProjects(t *testing.T) {
value := true
projects, err := GetProjects(&models.QueryParam{
projects, err := GetProjects(&models.ProjectQueryParam{
Public: &value,
})
if err != nil {
@ -953,16 +961,6 @@ func TestChangeUserProfile(t *testing.T) {
}
}
func TestGetRecentLogs(t *testing.T) {
logs, err := GetRecentLogs(currentUser.Username, 10, "2016-05-13 00:00:00", time.Now().String())
if err != nil {
t.Errorf("error occured in getting recent logs, error: %v", err)
}
if len(logs) <= 0 {
t.Errorf("get logs error, expected: %d, actual: %d", 1, len(logs))
}
}
var targetID, policyID, policyID2, policyID3, jobID, jobID2, jobID3 int64
func TestAddRepTarget(t *testing.T) {

View File

@ -190,7 +190,7 @@ func GetHasReadPermProjects(username string) ([]*models.Project, error) {
// GetTotalOfProjects returns the total count of projects
// according to the query conditions
func GetTotalOfProjects(query *models.QueryParam) (int64, error) {
func GetTotalOfProjects(query *models.ProjectQueryParam) (int64, error) {
var (
owner string
@ -210,7 +210,7 @@ func GetTotalOfProjects(query *models.QueryParam) (int64, error) {
}
}
sql, params := queryConditions(owner, name, public, member, role)
sql, params := projectQueryConditions(owner, name, public, member, role)
sql = `select count(*) ` + sql
@ -220,7 +220,7 @@ func GetTotalOfProjects(query *models.QueryParam) (int64, error) {
}
// GetProjects returns a project list according to the query conditions
func GetProjects(query *models.QueryParam) ([]*models.Project, error) {
func GetProjects(query *models.ProjectQueryParam) ([]*models.Project, error) {
var (
owner string
@ -246,7 +246,7 @@ func GetProjects(query *models.QueryParam) ([]*models.Project, error) {
}
}
sql, params := queryConditions(owner, name, public, member, role)
sql, params := projectQueryConditions(owner, name, public, member, role)
sql = `select distinct p.project_id, p.name, p.public, p.owner_id,
p.creation_time, p.update_time ` + sql
@ -265,7 +265,7 @@ func GetProjects(query *models.QueryParam) ([]*models.Project, error) {
return projects, err
}
func queryConditions(owner, name string, public *bool, member string,
func projectQueryConditions(owner, name string, public *bool, member string,
role int) (string, []interface{}) {
params := []interface{}{}

View File

@ -30,8 +30,19 @@ type AccessLog struct {
Operation string `orm:"column(operation)" json:"operation"`
OpTime time.Time `orm:"column(op_time)" json:"op_time"`
Keywords string `orm:"-" json:"keywords"`
BeginTime time.Time `orm:"-"`
BeginTimestamp int64 `orm:"-" json:"begin_timestamp"`
EndTime time.Time `orm:"-"`
EndTimestamp int64 `orm:"-" json:"end_timestamp"`
}
// LogQueryParam is used to set query conditions when listing
// access logs.
type LogQueryParam struct {
ProjectIDs []int64 // the IDs of projects to which the operation is done
Username string // the operator's username of the log
Repository string // repository name
Tag string // tag name
Operations []string // operations
BeginTime *time.Time // the time after which the operation is done
EndTime *time.Time // the time before which the operation is doen
Pagination *Pagination // pagination information
}

View File

@ -58,7 +58,7 @@ func (ps *ProjectSorter) Swap(i, j int) {
ps.Projects[i], ps.Projects[j] = ps.Projects[j], ps.Projects[i]
}
// QueryParam can be used to set query parameters when listing projects.
// ProjectQueryParam can be used to set query parameters when listing projects.
// The query condition will be set in the query if its corresponding field
// is not nil. Leave it empty if you don't want to apply this condition.
//
@ -69,7 +69,7 @@ func (ps *ProjectSorter) Swap(i, j int) {
// List all public projects the owner of which is user1: query := &QueryParam{Owner:"user1",Public:true}
// List projects which user1 is member of: query := &QueryParam{Member:&Member{Name:"user1"}}
// List projects which user1 is the project admin : query := &QueryParam{Memeber:&Member{Name:"user1",Role:1}}
type QueryParam struct {
type ProjectQueryParam struct {
Name string // the name of project
Owner string // the username of project owner
Public *bool // the project is public or not, can be ture, false and nil

View File

@ -106,7 +106,7 @@ func (f *fakePM) Update(projectIDOrName interface{}, project *models.Project) er
}
// nil implement
func (f *fakePM) GetAll(*models.QueryParam) ([]*models.Project, error) {
func (f *fakePM) GetAll(*models.ProjectQueryParam) ([]*models.Project, error) {
return []*models.Project{}, nil
}
@ -116,7 +116,7 @@ func (f *fakePM) GetHasReadPerm(username ...string) ([]*models.Project, error) {
}
// nil implement
func (f *fakePM) GetTotal(*models.QueryParam) (int64, error) {
func (f *fakePM) GetTotal(*models.ProjectQueryParam) (int64, error) {
return 0, nil
}

View File

@ -226,20 +226,14 @@ func (a testapi) StatisticGet(user usrInfo) (int, apilib.StatisticMap, error) {
return httpStatusCode, successPayload, err
}
func (a testapi) LogGet(user usrInfo, startTime, endTime, lines string) (int, []apilib.AccessLog, error) {
func (a testapi) LogGet(user usrInfo) (int, []apilib.AccessLog, error) {
_sling := sling.New().Get(a.basePath)
// create path and map variables
path := "/api/logs/"
fmt.Printf("logs path: %s\n", path)
_sling = _sling.Path(path)
type QueryParams struct {
StartTime string `url:"start_time,omitempty"`
EndTime string `url:"end_time,omitempty"`
Lines string `url:"lines,omitempty"`
}
_sling = _sling.QueryStruct(&QueryParams{StartTime: startTime, EndTime: endTime, Lines: lines})
var successPayload []apilib.AccessLog
code, body, err := request(_sling, jsonAcceptHeader, user)
if 200 == code && nil == err {

View File

@ -15,18 +15,17 @@
package api
import (
"net/http"
"strconv"
"time"
"fmt"
"github.com/vmware/harbor/src/common/dao"
"github.com/vmware/harbor/src/common/models"
"github.com/vmware/harbor/src/common/utils/log"
)
//LogAPI handles request api/logs
type LogAPI struct {
BaseController
username string
isSysAdmin bool
}
//Prepare validates the URL and the user
@ -36,53 +35,58 @@ func (l *LogAPI) Prepare() {
l.HandleUnauthorized()
return
}
l.username = l.SecurityCtx.GetUsername()
l.isSysAdmin = l.SecurityCtx.IsSysAdmin()
}
//Get returns the recent logs according to parameters
func (l *LogAPI) Get() {
var err error
startTime := l.GetString("start_time")
if len(startTime) != 0 {
i, err := strconv.ParseInt(startTime, 10, 64)
if err != nil {
log.Errorf("Parse startTime to int error, err: %v", err)
l.CustomAbort(http.StatusBadRequest, "startTime is not a valid integer")
}
startTime = time.Unix(i, 0).String()
page, size := l.GetPaginationParams()
query := &models.LogQueryParam{
Pagination: &models.Pagination{
Page: page,
Size: size,
},
}
endTime := l.GetString("end_time")
if len(endTime) != 0 {
j, err := strconv.ParseInt(endTime, 10, 64)
if !l.isSysAdmin {
projects, err := l.ProjectMgr.GetByMember(l.username)
if err != nil {
log.Errorf("Parse endTime to int error, err: %v", err)
l.CustomAbort(http.StatusBadRequest, "endTime is not a valid integer")
l.HandleInternalServerError(fmt.Sprintf(
"failed to get projects of user %s: %v", l.username, err))
return
}
endTime = time.Unix(j, 0).String()
if len(projects) == 0 {
l.SetPaginationHeader(0, page, size)
l.Data["json"] = nil
l.ServeJSON()
return
}
ids := []int64{}
for _, project := range projects {
ids = append(ids, project.ProjectID)
}
query.ProjectIDs = ids
}
var linesNum int
lines := l.GetString("lines")
if len(lines) != 0 {
linesNum, err = strconv.Atoi(lines)
if err != nil {
log.Errorf("Get parameters error--lines, err: %v", err)
l.CustomAbort(http.StatusBadRequest, "bad request of lines")
}
if linesNum <= 0 {
log.Warning("lines must be a positive integer")
l.CustomAbort(http.StatusBadRequest, "lines is 0 or negative")
}
} else if len(startTime) == 0 && len(endTime) == 0 {
linesNum = 10
}
var logList []models.AccessLog
logList, err = dao.GetRecentLogs(l.SecurityCtx.GetUsername(), linesNum, startTime, endTime)
total, err := dao.GetTotalOfAccessLogs(query)
if err != nil {
log.Errorf("Get recent logs error, err: %v", err)
l.CustomAbort(http.StatusInternalServerError, "Internal error")
l.HandleInternalServerError(fmt.Sprintf(
"failed to get total of access logs: %v", err))
return
}
l.Data["json"] = logList
logs, err := dao.GetAccessLogs(query)
if err != nil {
l.HandleInternalServerError(fmt.Sprintf(
"failed to get access logs: %v", err))
return
}
l.SetPaginationHeader(total, page, size)
l.Data["json"] = logs
l.ServeJSON()
}

View File

@ -15,11 +15,11 @@ package api
import (
"fmt"
"github.com/stretchr/testify/assert"
"github.com/vmware/harbor/tests/apitests/apilib"
"strconv"
"testing"
"time"
"github.com/stretchr/testify/assert"
"github.com/vmware/harbor/tests/apitests/apilib"
)
func TestLogGet(t *testing.T) {
@ -29,12 +29,11 @@ func TestLogGet(t *testing.T) {
apiTest := newHarborAPI()
//prepare for test
CommonAddUser()
var project apilib.ProjectReq
project.ProjectName = "my_project"
project.Public = 1
now := fmt.Sprintf("%v", time.Now().Unix())
statusCode, result, err := apiTest.LogGet(*admin, "0", now, "1000")
statusCode, result, err := apiTest.LogGet(*testUser)
if err != nil {
t.Error("Error while get log information", err.Error())
t.Log(err)
@ -46,7 +45,7 @@ func TestLogGet(t *testing.T) {
fmt.Println("result", result)
//add the project first.
fmt.Println("add the project first.")
reply, err := apiTest.ProjectsPost(*admin, project)
reply, err := apiTest.ProjectsPost(*testUser, project)
if err != nil {
t.Error("Error while creat project", err.Error())
t.Log(err)
@ -54,8 +53,7 @@ func TestLogGet(t *testing.T) {
assert.Equal(int(201), reply, "Case 2: Project creation status should be 201")
}
//case 1: right parameters, expect the right output
now = fmt.Sprintf("%v", time.Now().Unix())
statusCode, result, err = apiTest.LogGet(*admin, "0", now, "1000")
statusCode, result, err = apiTest.LogGet(*testUser)
if err != nil {
t.Error("Error while get log information", err.Error())
t.Log(err)
@ -71,64 +69,6 @@ func TestLogGet(t *testing.T) {
}
}
fmt.Println("log ", result)
//case 2: wrong format of start_time parameter, expect the wrong output
statusCode, result, err = apiTest.LogGet(*admin, "ss", now, "3")
if err != nil {
t.Error("Error occured while get log information since the format of start_time parameter is not right.", err.Error())
t.Log(err)
} else {
assert.Equal(int(400), statusCode, "Http status code should be 400")
}
//case 3: wrong format of end_time parameter, expect the wrong output
statusCode, result, err = apiTest.LogGet(*admin, "0", "cc", "3")
if err != nil {
t.Error("Error occured while get log information since the format of end_time parameter is not right.", err.Error())
t.Log(err)
} else {
assert.Equal(int(400), statusCode, "Http status code should be 400")
}
//case 4: wrong format of lines parameter, expect the wrong output
statusCode, result, err = apiTest.LogGet(*admin, "0", now, "s")
if err != nil {
t.Error("Error occured while get log information since the format of lines parameter is not right.", err.Error())
t.Log(err)
} else {
assert.Equal(int(400), statusCode, "Http status code should be 400")
}
//case 5: wrong format of lines parameter, expect the wrong output
statusCode, result, err = apiTest.LogGet(*admin, "0", now, "-5")
if err != nil {
t.Error("Error occured while get log information since the format of lines parameter is not right.", err.Error())
t.Log(err)
} else {
assert.Equal(int(400), statusCode, "Http status code should be 400")
}
//case 6: all parameters are null, expect the right output
statusCode, result, err = apiTest.LogGet(*admin, "", "", "")
if err != nil {
t.Error("Error while get log information", err.Error())
t.Log(err)
} else {
//default get 10 logs
if logNum+1 >= 10 {
logNum = 10
} else {
logNum++
}
assert.Equal(logNum, len(result), "lines of logs should be equal")
num, index := getLog(result)
if num != 1 {
assert.Equal(1, num, "add my_project log number should be 1")
} else {
assert.Equal("my_project/", result[index].RepoName, "RepoName should be equal")
assert.Equal("N/A", result[index].RepoTag, "RepoTag should be equal")
assert.Equal("create", result[index].Operation, "Operation should be equal")
}
}
//get the project
var projects []apilib.Project
@ -144,7 +84,7 @@ func TestLogGet(t *testing.T) {
//delete the project
projectID := strconv.Itoa(int(addProjectID))
httpStatusCode, err = apiTest.ProjectsDelete(*admin, projectID)
httpStatusCode, err = apiTest.ProjectsDelete(*testUser, projectID)
if err != nil {
t.Error("Error while delete project", err.Error())
t.Log(err)
@ -152,7 +92,7 @@ func TestLogGet(t *testing.T) {
assert.Equal(int(200), httpStatusCode, "Case 1: Project creation status should be 200")
//t.Log(result)
}
CommonDelUser()
fmt.Printf("\n")
}

View File

@ -18,6 +18,7 @@ import (
"fmt"
"net/http"
"regexp"
"strings"
"github.com/vmware/harbor/src/common"
"github.com/vmware/harbor/src/common/dao"
@ -258,7 +259,7 @@ func projectContainsPolicy(id int64) (bool, error) {
// TODO refacter pattern to:
// /api/repositories?owner=xxx&name=xxx&public=true&member=xxx&role=1&page=1&size=3
func (p *ProjectAPI) List() {
query := &models.QueryParam{}
query := &models.ProjectQueryParam{}
query.Name = p.GetString("project_name")
public := p.GetString("is_public")
@ -382,28 +383,49 @@ func (p *ProjectAPI) FilterAccessLog() {
var query models.AccessLog
p.DecodeJSONReq(&query)
query.ProjectID = p.project.ProjectID
query.BeginTime = time.Unix(query.BeginTimestamp, 0)
query.EndTime = time.Unix(query.EndTimestamp, 0)
page, pageSize := p.GetPaginationParams()
total, err := dao.GetTotalOfAccessLogs(query)
if err != nil {
log.Errorf("failed to get total of access log: %v", err)
p.CustomAbort(http.StatusInternalServerError, "")
queryParm := &models.LogQueryParam{
ProjectIDs: []int64{p.project.ProjectID},
Username: query.Username,
Repository: query.RepoName,
Tag: query.RepoTag,
}
logs, err := dao.GetAccessLogs(query, pageSize, pageSize*(page-1))
if len(query.Keywords) > 0 {
queryParm.Operations = strings.Split(query.Keywords, "/")
}
if query.BeginTimestamp > 0 {
beginTime := time.Unix(query.BeginTimestamp, 0)
queryParm.BeginTime = &beginTime
}
if query.EndTimestamp > 0 {
endTime := time.Unix(query.EndTimestamp, 0)
queryParm.EndTime = &endTime
}
page, pageSize := p.GetPaginationParams()
queryParm.Pagination = &models.Pagination{
Page: page,
Size: pageSize,
}
total, err := dao.GetTotalOfAccessLogs(queryParm)
if err != nil {
log.Errorf("failed to get access log: %v", err)
p.CustomAbort(http.StatusInternalServerError, "")
p.HandleInternalServerError(fmt.Sprintf(
"failed to get total of access log: %v", err))
return
}
logs, err := dao.GetAccessLogs(queryParm)
if err != nil {
p.HandleInternalServerError(fmt.Sprintf(
"failed to get access log: %v", err))
return
}
p.SetPaginationHeader(total, page, pageSize)
p.Data["json"] = logs
p.ServeJSON()
}

View File

@ -57,7 +57,6 @@ func (s *StatisticAPI) Prepare() {
// Get total projects and repos of the user
func (s *StatisticAPI) Get() {
statistic := map[string]int64{}
projects, err := s.ProjectMgr.GetPublic()
if err != nil {
s.HandleInternalServerError(fmt.Sprintf(
@ -95,7 +94,7 @@ func (s *StatisticAPI) Get() {
statistic[MRC] = n
statistic[TRC] = n
} else {
projects, err := s.ProjectMgr.GetAll(&models.QueryParam{
projects, err := s.ProjectMgr.GetAll(&models.ProjectQueryParam{
Member: &models.Member{
Name: s.username,
},

View File

@ -107,7 +107,7 @@ func (p *ProjectManager) GetRoles(username string, projectIDOrName interface{})
// GetPublic returns all public projects
func (p *ProjectManager) GetPublic() ([]*models.Project, error) {
t := true
return p.GetAll(&models.QueryParam{
return p.GetAll(&models.ProjectQueryParam{
Public: &t,
})
}
@ -115,7 +115,7 @@ func (p *ProjectManager) GetPublic() ([]*models.Project, error) {
// GetByMember returns all projects which the user is a member of
func (p *ProjectManager) GetByMember(username string) (
[]*models.Project, error) {
return p.GetAll(&models.QueryParam{
return p.GetAll(&models.ProjectQueryParam{
Member: &models.Member{
Name: username,
},
@ -190,13 +190,13 @@ func (p *ProjectManager) Update(projectIDOrName interface{},
}
// GetAll returns a project list according to the query parameters
func (p *ProjectManager) GetAll(query *models.QueryParam) (
func (p *ProjectManager) GetAll(query *models.ProjectQueryParam) (
[]*models.Project, error) {
return dao.GetProjects(query)
}
// GetTotal returns the total count according to the query parameters
func (p *ProjectManager) GetTotal(query *models.QueryParam) (
func (p *ProjectManager) GetTotal(query *models.ProjectQueryParam) (
int64, error) {
return dao.GetTotalOfProjects(query)
}

View File

@ -229,14 +229,14 @@ func TestGetTotal(t *testing.T) {
defer pm.Delete(id)
// get by name
total, err := pm.GetTotal(&models.QueryParam{
total, err := pm.GetTotal(&models.ProjectQueryParam{
Name: "get_total_test",
})
assert.Nil(t, err)
assert.Equal(t, int64(1), total)
// get by owner
total, err = pm.GetTotal(&models.QueryParam{
total, err = pm.GetTotal(&models.ProjectQueryParam{
Owner: "admin",
})
assert.Nil(t, err)
@ -244,7 +244,7 @@ func TestGetTotal(t *testing.T) {
// get by public
value := true
total, err = pm.GetTotal(&models.QueryParam{
total, err = pm.GetTotal(&models.ProjectQueryParam{
Public: &value,
})
assert.Nil(t, err)
@ -263,14 +263,14 @@ func TestGetAll(t *testing.T) {
defer pm.Delete(id)
// get by name
projects, err := pm.GetAll(&models.QueryParam{
projects, err := pm.GetAll(&models.ProjectQueryParam{
Name: "get_all_test",
})
assert.Nil(t, err)
assert.Equal(t, id, projects[0].ProjectID)
// get by owner
projects, err = pm.GetAll(&models.QueryParam{
projects, err = pm.GetAll(&models.ProjectQueryParam{
Owner: "admin",
})
assert.Nil(t, err)
@ -285,7 +285,7 @@ func TestGetAll(t *testing.T) {
// get by public
value := true
projects, err = pm.GetAll(&models.QueryParam{
projects, err = pm.GetAll(&models.ProjectQueryParam{
Public: &value,
})
assert.Nil(t, err)

View File

@ -33,9 +33,9 @@ type ProjectManager interface {
Delete(projectIDOrName interface{}) error
Update(projectIDOrName interface{}, project *models.Project) error
// GetAll returns a project list according to the query parameters
GetAll(query *models.QueryParam) ([]*models.Project, error)
GetAll(query *models.ProjectQueryParam) ([]*models.Project, error)
// GetTotal returns the total count according to the query parameters
GetTotal(query *models.QueryParam) (int64, error)
GetTotal(query *models.ProjectQueryParam) (int64, error)
// GetHasReadPerm returns a project list which the user has read
// permission of. The list should contains all public projects and
// projects which the user is a member of if the username is not nil

View File

@ -67,7 +67,7 @@ export class AccessLogDefaultService extends AccessLogService {
url = '/api/logs';
}
return this.http.get(url+`?lines=${lines}`, HTTP_JSON_OPTIONS).toPromise()
return this.http.get(url+`?page_size=${lines}`, HTTP_JSON_OPTIONS).toPromise()
.then(response => response.json() as AccessLog[])
.catch(error => Promise.reject(error));
}

View File

@ -49,7 +49,7 @@ export class AuditLogService {
}
getRecentLogs(lines: number): Observable<AuditLog[]> {
return this.http.get(logEndpoint + "?lines=" + lines, this.httpOptions)
return this.http.get(logEndpoint + "?page_size=" + lines, this.httpOptions)
.map(response => response.json() as AuditLog[])
.catch(error => Observable.throw(error));
}