diff --git a/api/search.go b/api/search.go index 043e540..d47bb58 100644 --- a/api/search.go +++ b/api/search.go @@ -38,17 +38,36 @@ type searchResult struct { } // Get ... -func (n *SearchAPI) Get() { - userID, ok := n.GetSession("userId").(int) +func (s *SearchAPI) Get() { + userID, ok := s.GetSession("userId").(int) if !ok { userID = dao.NonExistUserID } - keyword := n.GetString("q") - projects, err := dao.QueryRelevantProjects(userID) + + keyword := s.GetString("q") + + isSysAdmin, err := dao.IsAdminRole(userID) if err != nil { - log.Errorf("Failed to get projects of user id: %d, error: %v", userID, err) - n.CustomAbort(http.StatusInternalServerError, "Failed to get project search result") + log.Errorf("failed to check whether the user %d is system admin: %v", userID, err) + s.CustomAbort(http.StatusInternalServerError, "internal error") } + + var projects []models.Project + + if isSysAdmin { + projects, err = dao.GetAllProjects() + if err != nil { + log.Errorf("failed to get all projects: %v", err) + s.CustomAbort(http.StatusInternalServerError, "internal error") + } + } else { + projects, err = dao.GetUserRelevantProjects(userID) + if err != nil { + log.Errorf("failed to get user %d 's relevant projects: %v", userID, err) + s.CustomAbort(http.StatusInternalServerError, "internal error") + } + } + projectSorter := &utils.ProjectSorter{Projects: projects} sort.Sort(projectSorter) projectResult := []map[string]interface{}{} @@ -69,17 +88,17 @@ func (n *SearchAPI) Get() { repositories, err2 := svc_utils.GetRepoFromCache() if err2 != nil { log.Errorf("Failed to get repos from cache, error: %v", err2) - n.CustomAbort(http.StatusInternalServerError, "Failed to get repositories search result") + s.CustomAbort(http.StatusInternalServerError, "Failed to get repositories search result") } sort.Strings(repositories) repositoryResult := filterRepositories(repositories, projects, keyword) result := &searchResult{Project: projectResult, Repository: repositoryResult} - n.Data["json"] = result - n.ServeJSON() + s.Data["json"] = result + s.ServeJSON() } func filterRepositories(repositories []string, projects []models.Project, keyword string) []map[string]interface{} { - var i, j int = 0, 0 + i, j := 0, 0 result := []map[string]interface{}{} for i < len(repositories) && j < len(projects) { r := &utils.Repository{Name: repositories[i]} diff --git a/dao/project.go b/dao/project.go index 9eba4f7..6e01b07 100644 --- a/dao/project.go +++ b/dao/project.go @@ -208,18 +208,35 @@ func ToggleProjectPublicity(projectID int64, publicity int) error { return err } -// QueryRelevantProjects returns all projects that the user is a member of. -func QueryRelevantProjects(userID int) ([]models.Project, error) { +// GetUserRelevantProjects returns a project list, +// which satisfies the following conditions: +// 1. the project is not deleted +// 2. the prject is public or the user is a member of the project +func GetUserRelevantProjects(userID int) ([]models.Project, error) { o := orm.NewOrm() sql := `select distinct p.project_id, p.name, p.public from project p left join project_member pm on p.project_id = pm.project_id - left join user u on u.user_id = pm.user_id - where u.user_id = ? or p.public = 1 and p.deleted = 0` - var res []models.Project - _, err := o.Raw(sql, userID).QueryRows(&res) - if err != nil { + where (pm.user_id = ? or p.public = 1) and p.deleted = 0` + + var projects []models.Project + + if _, err := o.Raw(sql, userID).QueryRows(&projects); err != nil { return nil, err } - return res, err + + return projects, nil +} + +// GetAllProjects returns all projects which are not deleted +func GetAllProjects() ([]models.Project, error) { + o := orm.NewOrm() + sql := `select project_id, name, public + from project + where deleted = 0` + var projects []models.Project + if _, err := o.Raw(sql).QueryRows(&projects); err != nil { + return nil, err + } + return projects, nil }