remove common project code (#14939)

move project model from common to pkg

Signed-off-by: Wang Yan <wangyan@vmware.com>
This commit is contained in:
Wang Yan 2021-05-25 11:01:19 +08:00 committed by GitHub
parent d88dcffa03
commit 42a9d0d905
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
62 changed files with 452 additions and 1084 deletions

View File

@ -17,8 +17,8 @@ package dao
import (
"errors"
"fmt"
proModels "github.com/goharbor/harbor/src/pkg/project/models"
"strconv"
"strings"
"sync"
"github.com/astaxie/beego/orm"
@ -104,17 +104,11 @@ func GetOrmer() orm.Ormer {
return globalOrm
}
// IsDupRecErr checks if the error is due to a duplication of record, currently this
// works only for pgSQL
func IsDupRecErr(e error) bool {
return strings.Contains(e.Error(), "duplicate key value violates unique constraint")
}
// ClearTable is the shortcut for test cases, it should be called only in test cases.
func ClearTable(table string) error {
o := GetOrmer()
sql := fmt.Sprintf("delete from %s where 1=1", table)
if table == models.ProjectTable {
if table == proModels.ProjectTable {
sql = fmt.Sprintf("delete from %s where project_id > 1", table)
}
if table == models.UserTable {
@ -130,22 +124,6 @@ func ClearTable(table string) error {
return err
}
// PaginateForRawSQL ...
func PaginateForRawSQL(sql string, limit, offset int64) string {
return fmt.Sprintf("%s limit %d offset %d", sql, limit, offset)
}
// PaginateForQuerySetter ...
func PaginateForQuerySetter(qs orm.QuerySeter, page, size int64) orm.QuerySeter {
if size > 0 {
qs = qs.Limit(size)
if page > 0 {
qs = qs.Offset((page - 1) * size)
}
}
return qs
}
// implements github.com/golang-migrate/migrate/v4.Logger
type mLogger struct {
logger *log.Logger

View File

@ -16,17 +16,13 @@ package dao
import (
"context"
"fmt"
"os"
"testing"
"time"
"github.com/astaxie/beego/orm"
"github.com/goharbor/harbor/src/common/models"
"github.com/goharbor/harbor/src/lib/log"
libOrm "github.com/goharbor/harbor/src/lib/orm"
"github.com/goharbor/harbor/src/pkg/user"
"github.com/stretchr/testify/assert"
"os"
"testing"
)
var testCtx context.Context
@ -99,7 +95,6 @@ func cleanByUser(username string) {
const username string = "Tester01"
const password string = "Abc12345"
const projectName string = "test_project"
const repositoryName string = "test_repository"
func TestMain(m *testing.M) {
databases := []string{"postgresql"}
@ -153,87 +148,6 @@ func clearAll() {
}
}
var currentUser *models.User
func TestAddProject(t *testing.T) {
ctx := libOrm.Context()
var err error
currentUser, err = user.Mgr.GetByName(ctx, username)
if err != nil {
t.Errorf("Failed to get user by username: %s, error: %v", username, err)
}
project := models.Project{
OwnerID: currentUser.UserID,
Name: projectName,
CreationTime: time.Now(),
OwnerName: currentUser.Username,
}
_, err = AddProject(project)
if err != nil {
t.Errorf("Error occurred in AddProject: %v", err)
}
newProject, err := GetProjectByName(projectName)
if err != nil {
t.Errorf("Error occurred in GetProjectByName: %v", err)
}
if newProject == nil {
t.Errorf("No project found queried by project name: %v", projectName)
}
}
var currentProject *models.Project
func TestGetProject(t *testing.T) {
var err error
currentProject, err = GetProjectByName(projectName)
if err != nil {
t.Errorf("Error occurred in GetProjectByName: %v", err)
}
if currentProject == nil {
t.Errorf("No project found queried by project name: %v", projectName)
}
if currentProject.Name != projectName {
t.Errorf("Project name does not match, expected: %s, actual: %s", projectName, currentProject.Name)
}
}
func TestGetProjectById(t *testing.T) {
id := currentProject.ProjectID
p, err := GetProjectByID(id)
if err != nil {
t.Errorf("Error in GetProjectById: %v, id: %d", err, id)
}
if p.Name != currentProject.Name {
t.Errorf("project name does not match, expected: %s, actual: %s", currentProject.Name, p.Name)
}
}
func TestGetTotalOfProjects(t *testing.T) {
total, err := GetTotalOfProjects(nil)
if err != nil {
t.Fatalf("failed to get total of projects: %v", err)
}
if total != 2 {
t.Errorf("unexpected total: %d != 2", total)
}
}
func TestGetProjects(t *testing.T) {
projects, err := GetProjects(nil)
if err != nil {
t.Errorf("Error occurred in GetProjects: %v", err)
}
if len(projects) != 2 {
t.Errorf("Expected length of projects is 2, but actual: %d, the projects: %+v", len(projects), projects)
}
if projects[1].Name != projectName {
t.Errorf("Expected project name in the list: %s, actual: %s", projectName, projects[1].Name)
}
}
var targetID, policyID, policyID2, policyID3, jobID, jobID2, jobID3 int64
func TestGetOrmer(t *testing.T) {
@ -242,8 +156,3 @@ func TestGetOrmer(t *testing.T) {
t.Errorf("Error get ormer.")
}
}
func TestIsDupRecError(t *testing.T) {
assert.True(t, IsDupRecErr(fmt.Errorf("pq: duplicate key value violates unique constraint \"properties_k_key\"")))
assert.False(t, IsDupRecErr(fmt.Errorf("other error")))
}

View File

@ -1,303 +0,0 @@
// Copyright Project Harbor Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package dao
import (
"github.com/goharbor/harbor/src/common"
"github.com/goharbor/harbor/src/common/models"
"github.com/goharbor/harbor/src/common/utils"
"github.com/goharbor/harbor/src/lib/log"
libOrm "github.com/goharbor/harbor/src/lib/orm"
"fmt"
"time"
)
// AddProject adds a project to the database along with project roles information and access log records.
func AddProject(project models.Project) (int64, error) {
o := GetOrmer()
sql := "insert into project (owner_id, name, registry_id, creation_time, update_time, deleted) values (?, ?, ?, ?, ?, ?) RETURNING project_id"
var projectID int64
now := time.Now()
err := o.Raw(sql, project.OwnerID, project.Name, project.RegistryID, now, now, project.Deleted).QueryRow(&projectID)
if err != nil {
return 0, err
}
pmID, err := addProjectMember(models.Member{
ProjectID: projectID,
EntityID: project.OwnerID,
Role: common.RoleProjectAdmin,
EntityType: common.UserMember,
})
if err != nil {
return 0, err
}
if pmID == 0 {
return projectID, err
}
return projectID, nil
}
func addProjectMember(member models.Member) (int, error) {
log.Debugf("Adding project member %+v", member)
o := GetOrmer()
if member.EntityID <= 0 {
return 0, fmt.Errorf("invalid entity_id, member: %+v", member)
}
if member.ProjectID <= 0 {
return 0, fmt.Errorf("invalid project_id, member: %+v", member)
}
var pmID int
sql := "insert into project_member (project_id, entity_id , role, entity_type) values (?, ?, ?, ?) RETURNING id"
err := o.Raw(sql, member.ProjectID, member.EntityID, member.Role, member.EntityType).QueryRow(&pmID)
if err != nil {
return 0, err
}
return pmID, err
}
// GetProjectByID ...
func GetProjectByID(id int64) (*models.Project, error) {
o := GetOrmer()
sql := `select p.project_id, p.name, p.registry_id, u.username as owner_name, p.owner_id, p.creation_time, p.update_time
from project p left join harbor_user u on p.owner_id = u.user_id where p.deleted = false and p.project_id = ?`
queryParam := make([]interface{}, 1)
queryParam = append(queryParam, id)
p := []models.Project{}
count, err := o.Raw(sql, queryParam).QueryRows(&p)
if err != nil {
return nil, err
}
if count == 0 {
return nil, nil
}
return &p[0], nil
}
// GetProjectByName ...
func GetProjectByName(name string) (*models.Project, error) {
o := GetOrmer()
var p []models.Project
n, err := o.Raw(`select * from project where name = ? and deleted = false`, name).QueryRows(&p)
if err != nil {
return nil, err
}
if n == 0 {
return nil, nil
}
return &p[0], nil
}
// ProjectExistsByName returns whether the project exists according to its name.
func ProjectExistsByName(name string) bool {
o := GetOrmer()
return o.QueryTable("project").Filter("name", name).Exist()
}
// GetTotalOfProjects returns the total count of projects
// according to the query conditions
func GetTotalOfProjects(query *models.ProjectQueryParam) (int64, error) {
var pagination *models.Pagination
if query != nil {
pagination = query.Pagination
query.Pagination = nil
}
sql, params := projectQueryConditions(query)
if query != nil {
query.Pagination = pagination
}
sql = `select count(*) ` + sql
var total int64
err := GetOrmer().Raw(sql, params).QueryRow(&total)
return total, err
}
// GetProjects returns a project list according to the query conditions
func GetProjects(query *models.ProjectQueryParam) ([]*models.Project, error) {
sqlStr, queryParam := projectQueryConditions(query)
sqlStr = `select distinct p.project_id, p.name, p.registry_id, p.owner_id,
p.creation_time, p.update_time ` + sqlStr + ` order by p.name`
sqlStr, queryParam = CreatePagination(query, sqlStr, queryParam)
var projects []*models.Project
_, err := GetOrmer().Raw(sqlStr, queryParam).QueryRows(&projects)
return projects, err
}
// GetGroupProjects - Get user's all projects, including user is the user member of this project
// and the user is in the group which is a group member of this project.
func GetGroupProjects(groupIDs []int, query *models.ProjectQueryParam) ([]*models.Project, error) {
sql, params := projectQueryConditions(query)
sql = `select distinct p.project_id, p.name, p.registry_id, p.owner_id,
p.creation_time, p.update_time ` + sql
groupIDCondition := JoinNumberConditions(groupIDs)
if len(groupIDs) > 0 {
sql = fmt.Sprintf(
`%s union select distinct p.project_id, p.name, p.registry_id, p.owner_id, p.creation_time, p.update_time
from project p
left join project_member pm on p.project_id = pm.project_id
left join user_group ug on ug.id = pm.entity_id and pm.entity_type = 'g'
where p.deleted=false and ug.id in ( %s )`,
sql, groupIDCondition)
}
sql = sql + ` order by name`
sqlStr, queryParams := CreatePagination(query, sql, params)
log.Debugf("query sql:%v", sql)
var projects []*models.Project
_, err := GetOrmer().Raw(sqlStr, queryParams).QueryRows(&projects)
return projects, err
}
// GetTotalGroupProjects - Get the total count of projects, including user is the member of this project and the
// user is in the group, which is the group member of this project.
func GetTotalGroupProjects(groupIDs []int, query *models.ProjectQueryParam) (int, error) {
var sql string
sqlCondition, params := projectQueryConditions(query)
groupIDCondition := JoinNumberConditions(groupIDs)
if len(groupIDs) == 0 {
sql = `select count(1) ` + sqlCondition
} else {
sql = fmt.Sprintf(
`select count(1)
from ( select p.project_id %s union select p.project_id
from project p
left join project_member pm on p.project_id = pm.project_id
left join user_group ug on ug.id = pm.entity_id and pm.entity_type = 'g'
where p.deleted=false and ug.id in ( %s )) t`,
sqlCondition, groupIDCondition)
}
log.Debugf("query sql:%v", sql)
var count int
if err := GetOrmer().Raw(sql, params).QueryRow(&count); err != nil {
return 0, err
}
return count, nil
}
func projectQueryConditions(query *models.ProjectQueryParam) (string, []interface{}) {
params := []interface{}{}
sql := ` from project as p`
if query == nil {
sql += ` where p.deleted=false`
return sql, params
}
// if query.ProjectIDs is not nil but has no element, the query will returns no rows
if query.ProjectIDs != nil && len(query.ProjectIDs) == 0 {
sql += ` where 1 = 0`
return sql, params
}
if len(query.Owner) != 0 {
sql += ` join harbor_user u1
on p.owner_id = u1.user_id`
}
if query.Member != nil && len(query.Member.Name) != 0 {
sql += ` join project_member pm
on p.project_id = pm.project_id and pm.entity_type = 'u'
join harbor_user u2
on pm.entity_id=u2.user_id`
}
sql += ` where p.deleted=false`
if len(query.Owner) != 0 {
sql += ` and u1.username=?`
params = append(params, query.Owner)
}
if len(query.Name) != 0 {
sql += ` and p.name like ?`
params = append(params, "%"+libOrm.Escape(query.Name)+"%")
}
if query.RegistryID > 0 {
sql += ` and p.registry_id = ?`
params = append(params, query.RegistryID)
}
if query.Member != nil && len(query.Member.Name) != 0 {
sql += ` and u2.username=?`
params = append(params, query.Member.Name)
if query.Member.Role > 0 {
sql += ` and pm.role = ?`
roleID := 0
switch query.Member.Role {
case common.RoleProjectAdmin:
roleID = 1
case common.RoleDeveloper:
roleID = 2
case common.RoleGuest:
roleID = 3
case common.RoleMaintainer:
roleID = 4
case common.RoleLimitedGuest:
roleID = 5
}
params = append(params, roleID)
}
}
if len(query.ProjectIDs) > 0 {
sql += fmt.Sprintf(` and p.project_id in ( %s )`,
utils.ParamPlaceholderForIn(len(query.ProjectIDs)))
params = append(params, query.ProjectIDs)
}
return sql, params
}
// CreatePagination ...
func CreatePagination(query *models.ProjectQueryParam, sql string, params []interface{}) (string, []interface{}) {
if query != nil && query.Pagination != nil && query.Pagination.Size > 0 {
sql += ` limit ?`
params = append(params, query.Pagination.Size)
if query.Pagination.Page > 0 {
sql += ` offset ?`
params = append(params, (query.Pagination.Page-1)*query.Pagination.Size)
}
}
return sql, params
}
// DeleteProject ...
func DeleteProject(id int64) error {
project, err := GetProjectByID(id)
if err != nil {
return err
}
name := fmt.Sprintf("%s#%d", project.Name, project.ProjectID)
sql := `update project
set deleted = true, name = ?
where project_id = ?`
_, err = GetOrmer().Raw(sql, name, id).Exec()
return err
}

View File

@ -1,139 +0,0 @@
// Copyright Project Harbor Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package dao
import (
"fmt"
"strings"
"testing"
"github.com/goharbor/harbor/src/common/models"
)
func TestDeleteProject(t *testing.T) {
name := "project_for_test"
project := models.Project{
OwnerID: currentUser.UserID,
Name: name,
}
id, err := AddProject(project)
if err != nil {
t.Fatalf("failed to add project: %v", err)
}
defer func() {
if err := delProjPermanent(id); err != nil {
t.Errorf("failed to clear up project %d: %v", id, err)
}
}()
if err = DeleteProject(id); err != nil {
t.Fatalf("failed to delete project: %v", err)
}
p := &models.Project{}
if err = GetOrmer().Raw(`select * from project where project_id = ?`, id).
QueryRow(p); err != nil {
t.Fatalf("failed to get project: %v", err)
}
if !p.Deleted {
t.Errorf("unexpeced deleted column: %t != %t", p.Deleted, true)
}
deletedName := fmt.Sprintf("%s#%d", name, id)
if p.Name != deletedName {
t.Errorf("unexpected name: %s != %s", p.Name, deletedName)
}
}
func delProjPermanent(id int64) error {
_, err := GetOrmer().Raw(`delete from project_member
where project_id = ?`, id).Exec()
if err != nil {
return err
}
_, err = GetOrmer().QueryTable("project").
Filter("ProjectID", id).
Delete()
return err
}
func Test_projectQueryConditions(t *testing.T) {
type args struct {
query *models.ProjectQueryParam
}
tests := []struct {
name string
args args
want string
want1 []interface{}
}{
{"Query invalid projectID",
args{query: &models.ProjectQueryParam{ProjectIDs: []int64{}, Owner: "admin"}},
"from project as p where 1 = 0",
[]interface{}{}},
{"Query with valid projectID",
args{query: &models.ProjectQueryParam{ProjectIDs: []int64{2, 3}, Owner: "admin"}},
` from project as p join harbor_user u1
on p.owner_id = u1.user_id where p.deleted=false and u1.username=? and p.project_id in ( ?,? )`,
[]interface{}{2, 3}},
{"Query with valid page and member",
args{query: &models.ProjectQueryParam{ProjectIDs: []int64{2, 3}, Owner: "admin", Name: "sample", Member: &models.MemberQuery{Name: "name", Role: 1}, Pagination: &models.Pagination{Page: 1, Size: 20}}},
` from project as p join harbor_user u1
on p.owner_id = u1.user_id join project_member pm
on p.project_id = pm.project_id and pm.entity_type = 'u'
join harbor_user u2
on pm.entity_id=u2.user_id where p.deleted=false and u1.username=? and p.name like ? and u2.username=? and pm.role = ? and p.project_id in ( ?,? )`,
[]interface{}{1, []int64{2, 3}, 20, 0}},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, _ := projectQueryConditions(tt.args.query)
if strings.TrimSpace(got) != strings.TrimSpace(tt.want) {
t.Errorf("projectQueryConditions() got = %v\n, want %v", got, tt.want)
}
})
}
}
func TestProjetExistsByName(t *testing.T) {
name := "project_exist_by_name_test"
exist := ProjectExistsByName(name)
if exist {
t.Errorf("project %s expected to be not exist", name)
}
project := models.Project{
OwnerID: currentUser.UserID,
Name: name,
}
id, err := AddProject(project)
if err != nil {
t.Fatalf("failed to add project: %v", err)
}
defer func() {
if err := delProjPermanent(id); err != nil {
t.Errorf("failed to clear up project %d: %v", id, err)
}
}()
exist = ProjectExistsByName(name)
if !exist {
t.Errorf("project %s expected to be exist", name)
}
}

View File

@ -21,7 +21,6 @@ import (
func init() {
orm.RegisterModel(
new(User),
new(Project),
new(Role),
new(ResourceLabel),
new(JobLog),

View File

@ -1,38 +0,0 @@
// Copyright Project Harbor Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package models
import (
"github.com/goharbor/harbor/src/pkg/usergroup/model"
)
// Member holds the details of a member.
type Member struct {
ID int `orm:"pk;column(id)" json:"id"`
ProjectID int64 `orm:"column(project_id)" json:"project_id"`
Entityname string `orm:"column(entity_name)" json:"entity_name"`
Rolename string `json:"role_name"`
Role int `json:"role_id"`
EntityID int `orm:"column(entity_id)" json:"entity_id"`
EntityType string `orm:"column(entity_type)" json:"entity_type"`
}
// MemberReq - Create Project Member Request
type MemberReq struct {
ProjectID int64 `json:"project_id"`
Role int `json:"role_id,omitempty"`
MemberUser User `json:"member_user,omitempty"`
MemberGroup model.UserGroup `json:"member_group,omitempty"`
}

View File

@ -1,264 +0,0 @@
// Copyright Project Harbor Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package models
import (
"context"
"fmt"
"strconv"
"strings"
"time"
"github.com/astaxie/beego/orm"
"github.com/goharbor/harbor/src/pkg/allowlist/models"
"github.com/lib/pq"
)
const (
// ProjectTable is the table name for project
ProjectTable = "project"
// ProjectPublic means project is public
ProjectPublic = "public"
// ProjectPrivate means project is private
ProjectPrivate = "private"
)
// Project holds the details of a project.
type Project struct {
ProjectID int64 `orm:"pk;auto;column(project_id)" json:"project_id"`
OwnerID int `orm:"column(owner_id)" json:"owner_id"`
Name string `orm:"column(name)" json:"name" sort:"default"`
CreationTime time.Time `orm:"column(creation_time);auto_now_add" json:"creation_time"`
UpdateTime time.Time `orm:"column(update_time);auto_now" json:"update_time"`
Deleted bool `orm:"column(deleted)" json:"deleted"`
OwnerName string `orm:"-" json:"owner_name"`
Role int `orm:"-" json:"current_user_role_id"`
RoleList []int `orm:"-" json:"current_user_role_ids"`
RepoCount int64 `orm:"-" json:"repo_count"`
ChartCount uint64 `orm:"-" json:"chart_count"`
Metadata map[string]string `orm:"-" json:"metadata"`
CVEAllowlist models.CVEAllowlist `orm:"-" json:"cve_allowlist"`
RegistryID int64 `orm:"column(registry_id)" json:"registry_id"`
}
// GetMetadata ...
func (p *Project) GetMetadata(key string) (string, bool) {
if len(p.Metadata) == 0 {
return "", false
}
value, exist := p.Metadata[key]
return value, exist
}
// SetMetadata ...
func (p *Project) SetMetadata(key, value string) {
if p.Metadata == nil {
p.Metadata = map[string]string{}
}
p.Metadata[key] = value
}
// IsPublic ...
func (p *Project) IsPublic() bool {
public, exist := p.GetMetadata(ProMetaPublic)
if !exist {
return false
}
return isTrue(public)
}
// IsProxy returns true when the project type is proxy cache
func (p *Project) IsProxy() bool {
return p.RegistryID > 0
}
// ContentTrustEnabled ...
func (p *Project) ContentTrustEnabled() bool {
enabled, exist := p.GetMetadata(ProMetaEnableContentTrust)
if !exist {
return false
}
return isTrue(enabled)
}
// VulPrevented ...
func (p *Project) VulPrevented() bool {
prevent, exist := p.GetMetadata(ProMetaPreventVul)
if !exist {
return false
}
return isTrue(prevent)
}
// ReuseSysCVEAllowlist ...
func (p *Project) ReuseSysCVEAllowlist() bool {
r, ok := p.GetMetadata(ProMetaReuseSysCVEAllowlist)
if !ok {
return true
}
return isTrue(r)
}
// Severity ...
func (p *Project) Severity() string {
severity, exist := p.GetMetadata(ProMetaSeverity)
if !exist {
return ""
}
return severity
}
// AutoScan ...
func (p *Project) AutoScan() bool {
auto, exist := p.GetMetadata(ProMetaAutoScan)
if !exist {
return false
}
return isTrue(auto)
}
// FilterByPublic returns orm.QuerySeter with public filter
func (p *Project) FilterByPublic(ctx context.Context, qs orm.QuerySeter, key string, value interface{}) orm.QuerySeter {
subQuery := `SELECT project_id FROM project_metadata WHERE name = 'public' AND value = '%s'`
if isTrue(value) {
subQuery = fmt.Sprintf(subQuery, "true")
} else {
subQuery = fmt.Sprintf(subQuery, "false")
}
return qs.FilterRaw("project_id", fmt.Sprintf("IN (%s)", subQuery))
}
// FilterByOwner returns orm.QuerySeter with owner filter
func (p *Project) FilterByOwner(ctx context.Context, qs orm.QuerySeter, key string, value interface{}) orm.QuerySeter {
username, ok := value.(string)
if !ok {
return qs
}
return qs.FilterRaw("owner_id", fmt.Sprintf("IN (SELECT user_id FROM harbor_user WHERE username = %s)", pq.QuoteLiteral(username)))
}
// FilterByMember returns orm.QuerySeter with member filter
func (p *Project) FilterByMember(ctx context.Context, qs orm.QuerySeter, key string, value interface{}) orm.QuerySeter {
query, ok := value.(*MemberQuery)
if !ok {
return qs
}
subQuery := fmt.Sprintf(`SELECT project_id FROM project_member WHERE entity_id = %d AND entity_type = 'u'`, query.UserID)
if query.Role > 0 {
subQuery = fmt.Sprintf("%s AND role = %d", subQuery, query.Role)
}
if query.WithPublic {
subQuery = fmt.Sprintf("(%s) UNION (SELECT project_id FROM project_metadata WHERE name = 'public' AND value = 'true')", subQuery)
}
if len(query.GroupIDs) > 0 {
var elems []string
for _, groupID := range query.GroupIDs {
elems = append(elems, strconv.Itoa(groupID))
}
tpl := "(%s) UNION (SELECT project_id FROM project_member pm, user_group ug WHERE pm.entity_id = ug.id AND pm.entity_type = 'g' AND ug.id IN (%s))"
subQuery = fmt.Sprintf(tpl, subQuery, strings.TrimSpace(strings.Join(elems, ", ")))
}
return qs.FilterRaw("project_id", fmt.Sprintf("IN (%s)", subQuery))
}
func isTrue(i interface{}) bool {
switch value := i.(type) {
case bool:
return value
case string:
v := strings.ToLower(value)
return v == "true" || v == "1"
default:
return false
}
}
// 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.
//
// e.g.
// List all projects: query := nil
// List all public projects: query := &QueryParam{Public: true}
// List projects the owner of which is user1: query := &QueryParam{Owner:"user1"}
// 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{Member:&Member{Name:"user1",Role:1}}
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
RegistryID int64
Member *MemberQuery // the member of project
Pagination *Pagination // pagination information
ProjectIDs []int64 // project ID list
}
// MemberQuery filter by member's username and role
type MemberQuery struct {
UserID int // the user id
Name string // the username of member
Role int // the role of the member has to the project
GroupIDs []int // the group ID of current user belongs to
WithPublic bool // include the public projects for the member
}
// Pagination ...
type Pagination struct {
Page int64
Size int64
}
// Sorting sort by given field, ascending or descending
type Sorting struct {
Sort string // in format [+-]?<FIELD_NAME>, e.g. '+creation_time', '-creation_time'
}
// BaseProjectCollection contains the query conditions which can be used
// to get a project collection. The collection can be used as the base to
// do other filter
type BaseProjectCollection struct {
Public bool
Member string
}
// ProjectRequest holds informations that need for creating project API
type ProjectRequest struct {
Name string `json:"project_name"`
Public *int `json:"public"` // deprecated, reserved for project creation in replication
Metadata map[string]string `json:"metadata"`
CVEAllowlist models.CVEAllowlist `json:"cve_allowlist"`
StorageLimit *int64 `json:"storage_limit,omitempty"`
RegistryID int64 `json:"registry_id"`
}
// ProjectQueryResult ...
type ProjectQueryResult struct {
Total int64
Projects []*Project
}
// TableName is required by beego orm to map Project to table project
func (p *Project) TableName() string {
return ProjectTable
}

View File

@ -24,14 +24,15 @@ import (
"github.com/goharbor/harbor/src/pkg/permission/evaluator/namespace"
"github.com/goharbor/harbor/src/pkg/permission/evaluator/rbac"
"github.com/goharbor/harbor/src/pkg/permission/types"
proModels "github.com/goharbor/harbor/src/pkg/project/models"
)
// RBACUserBuilder builder to make types.RBACUser for the project
type RBACUserBuilder func(context.Context, *models.Project) types.RBACUser
type RBACUserBuilder func(context.Context, *proModels.Project) types.RBACUser
// NewBuilderForUser create a builder for the local user
func NewBuilderForUser(user *models.User, ctl project.Controller) RBACUserBuilder {
return func(ctx context.Context, p *models.Project) types.RBACUser {
return func(ctx context.Context, p *proModels.Project) types.RBACUser {
if user == nil {
// anonymous access
return &rbacUser{
@ -56,9 +57,9 @@ func NewBuilderForUser(user *models.User, ctl project.Controller) RBACUserBuilde
// NewBuilderForPolicies create a builder for the policies
func NewBuilderForPolicies(username string, policies []*types.Policy,
filters ...func(*models.Project, []*types.Policy) []*types.Policy) RBACUserBuilder {
filters ...func(*proModels.Project, []*types.Policy) []*types.Policy) RBACUserBuilder {
return func(ctx context.Context, p *models.Project) types.RBACUser {
return func(ctx context.Context, p *proModels.Project) types.RBACUser {
for _, filter := range filters {
policies = filter(p, policies)
}

View File

@ -21,13 +21,14 @@ import (
"github.com/goharbor/harbor/src/common"
"github.com/goharbor/harbor/src/common/models"
proModels "github.com/goharbor/harbor/src/pkg/project/models"
projecttesting "github.com/goharbor/harbor/src/testing/controller/project"
"github.com/goharbor/harbor/src/testing/mock"
"github.com/stretchr/testify/assert"
)
var (
public = &models.Project{
public = &proModels.Project{
ProjectID: 1,
Name: "public_project",
OwnerID: 1,
@ -36,7 +37,7 @@ var (
},
}
private = &models.Project{
private = &proModels.Project{
ProjectID: 2,
Name: "private_project",
OwnerID: 1,

View File

@ -15,8 +15,8 @@
package project
import (
"github.com/goharbor/harbor/src/common/models"
"github.com/goharbor/harbor/src/pkg/permission/types"
"github.com/goharbor/harbor/src/pkg/project/models"
)
type rbacUser struct {

View File

@ -16,20 +16,19 @@ package local
import (
"context"
rbac_project "github.com/goharbor/harbor/src/common/rbac/project"
"testing"
"github.com/goharbor/harbor/src/common"
"github.com/goharbor/harbor/src/common/models"
"github.com/goharbor/harbor/src/common/rbac"
"github.com/goharbor/harbor/src/controller/project"
rbac_project "github.com/goharbor/harbor/src/common/rbac/project"
proModels "github.com/goharbor/harbor/src/pkg/project/models"
projecttesting "github.com/goharbor/harbor/src/testing/controller/project"
"github.com/goharbor/harbor/src/testing/mock"
"github.com/stretchr/testify/assert"
"testing"
)
var (
public = &project.Project{
public = &proModels.Project{
ProjectID: 1,
Name: "public_project",
OwnerID: 1,
@ -38,7 +37,7 @@ var (
},
}
private = &models.Project{
private = &proModels.Project{
ProjectID: 2,
Name: "private_project",
OwnerID: 1,

View File

@ -20,8 +20,8 @@ import (
"github.com/goharbor/harbor/src/common/rbac/project"
"testing"
"github.com/goharbor/harbor/src/common/models"
"github.com/goharbor/harbor/src/common/rbac"
proModels "github.com/goharbor/harbor/src/pkg/project/models"
projecttesting "github.com/goharbor/harbor/src/testing/controller/project"
"github.com/goharbor/harbor/src/testing/mock"
"github.com/stretchr/testify/suite"
@ -85,7 +85,7 @@ func (p *proxyCacheSecretTestSuite) TestCan() {
// pass for action pull
action = rbac.ActionPull
resource = project.NewNamespace(1).Resource(rbac.ResourceRepository)
p.ctl.On("Get", mock.Anything, mock.Anything).Return(&models.Project{
p.ctl.On("Get", mock.Anything, mock.Anything).Return(&proModels.Project{
ProjectID: 1,
Name: "library",
}, nil)
@ -98,7 +98,7 @@ func (p *proxyCacheSecretTestSuite) TestCan() {
// pass for action push
action = rbac.ActionPush
resource = project.NewNamespace(1).Resource(rbac.ResourceRepository)
p.ctl.On("Get", mock.Anything, mock.Anything).Return(&models.Project{
p.ctl.On("Get", mock.Anything, mock.Anything).Return(&proModels.Project{
ProjectID: 1,
Name: "library",
}, nil)

View File

@ -22,11 +22,11 @@ import (
"strings"
"sync"
"github.com/goharbor/harbor/src/common/models"
"github.com/goharbor/harbor/src/common/rbac"
"github.com/goharbor/harbor/src/controller/project"
"github.com/goharbor/harbor/src/pkg/permission/evaluator"
"github.com/goharbor/harbor/src/pkg/permission/types"
"github.com/goharbor/harbor/src/pkg/project/models"
"github.com/goharbor/harbor/src/pkg/robot/model"
)

View File

@ -21,9 +21,9 @@ import (
"reflect"
"testing"
"github.com/goharbor/harbor/src/common/models"
"github.com/goharbor/harbor/src/common/rbac"
"github.com/goharbor/harbor/src/pkg/permission/types"
proModels "github.com/goharbor/harbor/src/pkg/project/models"
"github.com/goharbor/harbor/src/pkg/robot/model"
projecttesting "github.com/goharbor/harbor/src/testing/controller/project"
"github.com/goharbor/harbor/src/testing/mock"
@ -31,7 +31,7 @@ import (
)
var (
private = &models.Project{
private = &proModels.Project{
Name: "testrobot",
OwnerID: 1,
}
@ -150,7 +150,7 @@ func TestHasPushPullPerm(t *testing.T) {
func Test_filterRobotPolicies(t *testing.T) {
type args struct {
p *models.Project
p *proModels.Project
policies []*types.Policy
}
tests := []struct {
@ -161,7 +161,7 @@ func Test_filterRobotPolicies(t *testing.T) {
{
"policies of one project",
args{
&models.Project{ProjectID: 1},
&proModels.Project{ProjectID: 1},
[]*types.Policy{
{Resource: "/project/1/repository", Action: "pull", Effect: "allow"},
},
@ -173,7 +173,7 @@ func Test_filterRobotPolicies(t *testing.T) {
{
"policies of multi projects",
args{
&models.Project{ProjectID: 1},
&proModels.Project{ProjectID: 1},
[]*types.Policy{
{Resource: "/project/1/repository", Action: "pull", Effect: "allow"},
{Resource: "/project/2/repository", Action: "pull", Effect: "allow"},

View File

@ -17,12 +17,12 @@ package internal
import (
"testing"
"github.com/goharbor/harbor/src/common/models"
"github.com/goharbor/harbor/src/controller/artifact"
"github.com/goharbor/harbor/src/controller/project"
"github.com/goharbor/harbor/src/controller/scan"
"github.com/goharbor/harbor/src/lib/errors"
"github.com/goharbor/harbor/src/lib/orm"
proModels "github.com/goharbor/harbor/src/pkg/project/models"
projecttesting "github.com/goharbor/harbor/src/testing/controller/project"
scantesting "github.com/goharbor/harbor/src/testing/controller/scan"
ormtesting "github.com/goharbor/harbor/src/testing/lib/orm"
@ -65,9 +65,9 @@ func (suite *AutoScanTestSuite) TestGetProjectFailed() {
}
func (suite *AutoScanTestSuite) TestAutoScanDisabled() {
mock.OnAnything(suite.projectController, "Get").Return(&models.Project{
mock.OnAnything(suite.projectController, "Get").Return(&proModels.Project{
Metadata: map[string]string{
models.ProMetaAutoScan: "false",
proModels.ProMetaAutoScan: "false",
},
}, nil)
@ -78,9 +78,9 @@ func (suite *AutoScanTestSuite) TestAutoScanDisabled() {
}
func (suite *AutoScanTestSuite) TestAutoScan() {
mock.OnAnything(suite.projectController, "Get").Return(&models.Project{
mock.OnAnything(suite.projectController, "Get").Return(&proModels.Project{
Metadata: map[string]string{
models.ProMetaAutoScan: "true",
proModels.ProMetaAutoScan: "true",
},
}, nil)
@ -93,9 +93,9 @@ func (suite *AutoScanTestSuite) TestAutoScan() {
}
func (suite *AutoScanTestSuite) TestAutoScanFailed() {
mock.OnAnything(suite.projectController, "Get").Return(&models.Project{
mock.OnAnything(suite.projectController, "Get").Return(&proModels.Project{
Metadata: map[string]string{
models.ProMetaAutoScan: "true",
proModels.ProMetaAutoScan: "true",
},
}, nil)

View File

@ -19,7 +19,6 @@ import (
"fmt"
beegorm "github.com/astaxie/beego/orm"
"github.com/goharbor/harbor/src/common/models"
"github.com/goharbor/harbor/src/controller/event"
"github.com/goharbor/harbor/src/controller/event/handler/util"
"github.com/goharbor/harbor/src/controller/project"
@ -28,6 +27,7 @@ import (
"github.com/goharbor/harbor/src/pkg/notification"
"github.com/goharbor/harbor/src/pkg/notifier/model"
notifyModel "github.com/goharbor/harbor/src/pkg/notifier/model"
proModels "github.com/goharbor/harbor/src/pkg/project/models"
"github.com/goharbor/harbor/src/pkg/repository"
)
@ -90,15 +90,15 @@ func (a *Handler) handle(ctx context.Context, event *event.ArtifactEvent) error
return nil
}
func (a *Handler) constructArtifactPayload(event *event.ArtifactEvent, project *models.Project) (*model.Payload, error) {
func (a *Handler) constructArtifactPayload(event *event.ArtifactEvent, project *proModels.Project) (*model.Payload, error) {
repoName := event.Repository
if repoName == "" {
return nil, fmt.Errorf("invalid %s event with empty repo name", event.EventType)
}
repoType := models.ProjectPrivate
repoType := proModels.ProjectPrivate
if project.IsPublic() {
repoType = models.ProjectPublic
repoType = proModels.ProjectPublic
}
imageName := util.GetNameFromImgRepoFullName(repoName)

View File

@ -4,11 +4,11 @@ import (
"context"
"errors"
"fmt"
proModels "github.com/goharbor/harbor/src/pkg/project/models"
"strings"
"github.com/goharbor/harbor/src/lib/config"
commonModels "github.com/goharbor/harbor/src/common/models"
"github.com/goharbor/harbor/src/controller/event"
"github.com/goharbor/harbor/src/controller/event/handler/util"
ctlModel "github.com/goharbor/harbor/src/controller/event/model"
@ -73,7 +73,7 @@ func (r *ReplicationHandler) IsStateful() bool {
return false
}
func constructReplicationPayload(event *event.ReplicationEvent) (*model.Payload, *commonModels.Project, error) {
func constructReplicationPayload(event *event.ReplicationEvent) (*model.Payload, *proModels.Project, error) {
ctx := orm.Context()
task, err := replication.Ctl.GetTask(ctx, event.ReplicationTaskID)
if err != nil {

View File

@ -16,13 +16,13 @@ package artifact
import (
"context"
proModels "github.com/goharbor/harbor/src/pkg/project/models"
"testing"
"time"
"github.com/goharbor/harbor/src/lib/config"
common_dao "github.com/goharbor/harbor/src/common/dao"
"github.com/goharbor/harbor/src/common/models"
"github.com/goharbor/harbor/src/controller/event"
"github.com/goharbor/harbor/src/controller/project"
repctl "github.com/goharbor/harbor/src/controller/replication"
@ -67,7 +67,7 @@ func TestReplicationHandler_Handle(t *testing.T) {
},
}, nil)
mock.OnAnything(projectCtl, "GetByName").Return(&models.Project{ProjectID: 1}, nil)
mock.OnAnything(projectCtl, "GetByName").Return(&proModels.Project{ProjectID: 1}, nil)
handler := &ReplicationHandler{}

View File

@ -20,13 +20,13 @@ import (
"fmt"
"github.com/goharbor/harbor/src/lib/config"
"github.com/goharbor/harbor/src/common/models"
"github.com/goharbor/harbor/src/controller/event"
"github.com/goharbor/harbor/src/controller/event/handler/util"
"github.com/goharbor/harbor/src/controller/project"
"github.com/goharbor/harbor/src/lib/log"
"github.com/goharbor/harbor/src/pkg/notification"
"github.com/goharbor/harbor/src/pkg/notifier/model"
proModels "github.com/goharbor/harbor/src/pkg/project/models"
)
// Handler preprocess chart event data
@ -83,10 +83,10 @@ func (cph *Handler) IsStateful() bool {
return false
}
func constructChartPayload(event *event.ChartEvent, project *models.Project) (*model.Payload, error) {
repoType := models.ProjectPrivate
func constructChartPayload(event *event.ChartEvent, project *proModels.Project) (*model.Payload, error) {
repoType := proModels.ProjectPrivate
if project.IsPublic() {
repoType = models.ProjectPublic
repoType = proModels.ProjectPublic
}
payload := &model.Payload{

View File

@ -20,10 +20,10 @@ import (
"github.com/goharbor/harbor/src/lib/config"
_ "github.com/goharbor/harbor/src/pkg/config/db"
_ "github.com/goharbor/harbor/src/pkg/config/inmemory"
proModels "github.com/goharbor/harbor/src/pkg/project/models"
"os"
"testing"
"github.com/goharbor/harbor/src/common/models"
"github.com/goharbor/harbor/src/controller/event"
"github.com/goharbor/harbor/src/controller/project"
"github.com/goharbor/harbor/src/pkg/notification"
@ -57,15 +57,15 @@ func TestChartPreprocessHandler_Handle(t *testing.T) {
project.Ctl = projectCtl
name := "project_for_test_chart_event_preprocess"
mock.OnAnything(projectCtl, "Get").Return(func(ctx context.Context, projectIDOrName interface{}, options ...project.Option) *models.Project {
return &models.Project{
mock.OnAnything(projectCtl, "Get").Return(func(ctx context.Context, projectIDOrName interface{}, options ...project.Option) *proModels.Project {
return &proModels.Project{
Name: name,
OwnerID: 1,
Metadata: map[string]string{
models.ProMetaEnableContentTrust: "true",
models.ProMetaPreventVul: "true",
models.ProMetaSeverity: "Low",
models.ProMetaReuseSysCVEAllowlist: "false",
proModels.ProMetaEnableContentTrust: "true",
proModels.ProMetaPreventVul: "true",
proModels.ProMetaSeverity: "Low",
proModels.ProMetaReuseSysCVEAllowlist: "false",
},
}
}, nil)

View File

@ -19,7 +19,6 @@ import (
"errors"
"fmt"
"github.com/goharbor/harbor/src/common/models"
"github.com/goharbor/harbor/src/controller/event"
"github.com/goharbor/harbor/src/controller/event/handler/util"
"github.com/goharbor/harbor/src/controller/project"
@ -28,6 +27,7 @@ import (
"github.com/goharbor/harbor/src/pkg/notification"
"github.com/goharbor/harbor/src/pkg/notifier/model"
notifyModel "github.com/goharbor/harbor/src/pkg/notifier/model"
proModels "github.com/goharbor/harbor/src/pkg/project/models"
)
// Handler preprocess image event data
@ -88,9 +88,9 @@ func constructQuotaPayload(event *event.QuotaEvent) (*model.Payload, error) {
return nil, fmt.Errorf("invalid %s event with empty repo name", event.EventType)
}
repoType := models.ProjectPrivate
repoType := proModels.ProjectPrivate
if event.Project.IsPublic() {
repoType = models.ProjectPublic
repoType = proModels.ProjectPublic
}
imageName := util.GetNameFromImgRepoFullName(repoName)

View File

@ -21,12 +21,12 @@ import (
"github.com/goharbor/harbor/src/lib/config"
_ "github.com/goharbor/harbor/src/pkg/config/inmemory"
policy_model "github.com/goharbor/harbor/src/pkg/notification/policy/model"
proModels "github.com/goharbor/harbor/src/pkg/project/models"
"github.com/goharbor/harbor/src/testing/mock"
"testing"
"time"
"github.com/goharbor/harbor/src/common"
"github.com/goharbor/harbor/src/common/models"
"github.com/goharbor/harbor/src/pkg/notification"
"github.com/goharbor/harbor/src/pkg/notification/policy"
"github.com/goharbor/harbor/src/pkg/notifier"
@ -65,7 +65,7 @@ func (suite *QuotaPreprocessHandlerSuite) SetupSuite() {
OccurAt: time.Now().UTC(),
RepoName: "hello-world",
Resource: res,
Project: &models.Project{
Project: &proModels.Project{
ProjectID: 1,
Name: "library",
},

View File

@ -19,7 +19,6 @@ import (
"time"
o "github.com/astaxie/beego/orm"
"github.com/goharbor/harbor/src/common/models"
"github.com/goharbor/harbor/src/controller/artifact"
"github.com/goharbor/harbor/src/controller/event"
"github.com/goharbor/harbor/src/controller/event/handler/util"
@ -30,6 +29,7 @@ import (
"github.com/goharbor/harbor/src/lib/orm"
"github.com/goharbor/harbor/src/pkg/notification"
"github.com/goharbor/harbor/src/pkg/notifier/model"
proModels "github.com/goharbor/harbor/src/pkg/project/models"
v1 "github.com/goharbor/harbor/src/pkg/scan/rest/v1"
)
@ -88,10 +88,10 @@ func (si *Handler) IsStateful() bool {
return false
}
func constructScanImagePayload(event *event.ScanImageEvent, project *models.Project) (*model.Payload, error) {
repoType := models.ProjectPrivate
func constructScanImagePayload(event *event.ScanImageEvent, project *proModels.Project) (*model.Payload, error) {
repoType := proModels.ProjectPrivate
if project.IsPublic() {
repoType = models.ProjectPublic
repoType = proModels.ProjectPublic
}
repoName := util.GetNameFromImgRepoFullName(event.Artifact.Repository)

View File

@ -1,9 +1,9 @@
package metadata
import (
proModels "github.com/goharbor/harbor/src/pkg/project/models"
"time"
"github.com/goharbor/harbor/src/common/models"
event2 "github.com/goharbor/harbor/src/controller/event"
"github.com/goharbor/harbor/src/lib/errors"
"github.com/goharbor/harbor/src/pkg/notifier/event"
@ -11,7 +11,7 @@ import (
// QuotaMetaData defines quota related event data
type QuotaMetaData struct {
Project *models.Project
Project *proModels.Project
RepoName string
Tag string
Digest string

View File

@ -16,9 +16,9 @@ package event
import (
"fmt"
proModels "github.com/goharbor/harbor/src/pkg/project/models"
"time"
"github.com/goharbor/harbor/src/common/models"
"github.com/goharbor/harbor/src/lib/selector"
"github.com/goharbor/harbor/src/pkg/artifact"
"github.com/goharbor/harbor/src/pkg/audit/model"
@ -318,7 +318,7 @@ func (c *ChartEvent) String() string {
// QuotaEvent is project quota related event data to publish
type QuotaEvent struct {
EventType string
Project *models.Project
Project *proModels.Project
Resource *ImgResource
OccurAt time.Time
RepoName string

View File

@ -3,10 +3,10 @@ package immutable
import (
"github.com/goharbor/harbor/src/lib/orm"
"github.com/goharbor/harbor/src/lib/q"
"github.com/goharbor/harbor/src/pkg/project"
proModels "github.com/goharbor/harbor/src/pkg/project/models"
"testing"
"github.com/goharbor/harbor/src/common/dao"
"github.com/goharbor/harbor/src/common/models"
"github.com/goharbor/harbor/src/common/utils/test"
"github.com/goharbor/harbor/src/pkg/immutable/model"
htesting "github.com/goharbor/harbor/src/testing"
@ -37,13 +37,14 @@ func (s *ControllerTestSuite) SetupSuite() {
func (s *ControllerTestSuite) TestImmutableRule() {
var err error
ctx := s.Context()
projectID, err := dao.AddProject(models.Project{
Name: "TestImmutableRule",
projectID, err := project.Mgr.Create(ctx, &proModels.Project{
Name: "testimmutablerule",
OwnerID: 1,
})
if s.Nil(err) {
defer dao.DeleteProject(projectID)
defer project.Mgr.Delete(ctx, projectID)
}
rule := &model.Metadata{

View File

@ -17,10 +17,10 @@ package preheat
import (
"context"
"fmt"
proModels "github.com/goharbor/harbor/src/pkg/project/models"
"strings"
tk "github.com/docker/distribution/registry/auth/token"
"github.com/goharbor/harbor/src/common/models"
"github.com/goharbor/harbor/src/controller/artifact"
"github.com/goharbor/harbor/src/controller/project"
"github.com/goharbor/harbor/src/controller/scan"
@ -344,7 +344,7 @@ func (de *defaultEnforcer) PreheatArtifact(ctx context.Context, art *artifact.Ar
}
// getCandidates get the initial candidates by evaluating the policy
func (de *defaultEnforcer) getCandidates(ctx context.Context, ps *pol.Schema, p *models.Project) ([]*selector.Candidate, error) {
func (de *defaultEnforcer) getCandidates(ctx context.Context, ps *pol.Schema, p *proModels.Project) ([]*selector.Candidate, error) {
// Get the initial candidates
// Here we have a hidden filter, the artifact type filter.
// Only get the image type at this moment.
@ -480,7 +480,7 @@ func (de *defaultEnforcer) startTask(ctx context.Context, executionID int64, can
}
// getVulnerabilitySev gets the severity code value for the given artifact with allowlist option set
func (de *defaultEnforcer) getVulnerabilitySev(ctx context.Context, p *models.Project, art *artifact.Artifact) (uint, error) {
func (de *defaultEnforcer) getVulnerabilitySev(ctx context.Context, p *proModels.Project, art *artifact.Artifact) (uint, error) {
vulnerable, err := de.scanCtl.GetVulnerable(ctx, art, p.CVEAllowlist.CVESet())
if err != nil {
if errors.IsNotFoundErr(err) {
@ -505,7 +505,7 @@ func (de *defaultEnforcer) getVulnerabilitySev(ctx context.Context, p *models.Pr
}
// toCandidates converts the artifacts to filtering candidates
func (de *defaultEnforcer) toCandidates(ctx context.Context, p *models.Project, arts []*artifact.Artifact) ([]*selector.Candidate, error) {
func (de *defaultEnforcer) toCandidates(ctx context.Context, p *proModels.Project, arts []*artifact.Artifact) ([]*selector.Candidate, error) {
// Convert to filtering candidates first
candidates := make([]*selector.Candidate, 0)
@ -539,7 +539,7 @@ func (de *defaultEnforcer) toCandidates(ctx context.Context, p *models.Project,
}
// getProject gets the full metadata of the specified project
func (de *defaultEnforcer) getProject(ctx context.Context, id int64) (*models.Project, error) {
func (de *defaultEnforcer) getProject(ctx context.Context, id int64) (*proModels.Project, error) {
// Get project info with CVE allow list and metadata
return de.proCtl.Get(ctx, id, project.WithEffectCVEAllowlist())
}
@ -599,7 +599,7 @@ func checkProviderHealthy(inst *provider.Instance) error {
// Check the project security settings and override the related settings in the policy if necessary.
// NOTES: if the security settings (relevant with signature and vulnerability) are set at the project configuration,
// the corresponding filters of P2P preheat policy will be set using the relevant settings of project configurations.
func overrideSecuritySettings(p *pol.Schema, pro *models.Project) [][]interface{} {
func overrideSecuritySettings(p *pol.Schema, pro *proModels.Project) [][]interface{} {
if p == nil || pro == nil {
return nil
}

View File

@ -17,12 +17,12 @@ package preheat
import (
"context"
"fmt"
proModels "github.com/goharbor/harbor/src/pkg/project/models"
"net/http"
"net/http/httptest"
"testing"
"time"
"github.com/goharbor/harbor/src/common/models"
car "github.com/goharbor/harbor/src/controller/artifact"
"github.com/goharbor/harbor/src/controller/scan"
"github.com/goharbor/harbor/src/controller/tag"
@ -118,7 +118,7 @@ func (suite *EnforcerTestSuite) SetupSuite() {
(int64)(1),
mock.Anything,
mock.Anything,
).Return(&models.Project{
).Return(&proModels.Project{
ProjectID: 1,
Name: "library",
CVEAllowlist: models2.CVEAllowlist{},

View File

@ -18,6 +18,7 @@ import (
"context"
"fmt"
"github.com/goharbor/harbor/src/controller/tag"
proModels "github.com/goharbor/harbor/src/pkg/project/models"
"io"
"strings"
"sync"
@ -25,7 +26,6 @@ import (
"github.com/docker/distribution"
"github.com/docker/distribution/manifest/manifestlist"
"github.com/goharbor/harbor/src/common/models"
"github.com/goharbor/harbor/src/controller/artifact"
"github.com/goharbor/harbor/src/controller/blob"
"github.com/goharbor/harbor/src/controller/event/operator"
@ -60,7 +60,7 @@ type Controller interface {
UseLocalManifest(ctx context.Context, art lib.ArtifactInfo, remote RemoteInterface) (bool, *ManifestList, error)
// ProxyBlob proxy the blob request to the remote server, p is the proxy project
// art is the ArtifactInfo which includes the digest of the blob
ProxyBlob(ctx context.Context, p *models.Project, art lib.ArtifactInfo) (int64, io.ReadCloser, error)
ProxyBlob(ctx context.Context, p *proModels.Project, art lib.ArtifactInfo) (int64, io.ReadCloser, error)
// ProxyManifest proxy the manifest request to the remote server, p is the proxy project,
// art is the ArtifactInfo which includes the tag or digest of the manifest
ProxyManifest(ctx context.Context, art lib.ArtifactInfo, remote RemoteInterface) (distribution.Manifest, error)
@ -232,7 +232,7 @@ func (c *controller) HeadManifest(ctx context.Context, art lib.ArtifactInfo, rem
ref := getReference(art)
return remote.ManifestExist(remoteRepo, ref)
}
func (c *controller) ProxyBlob(ctx context.Context, p *models.Project, art lib.ArtifactInfo) (int64, io.ReadCloser, error) {
func (c *controller) ProxyBlob(ctx context.Context, p *proModels.Project, art lib.ArtifactInfo) (int64, io.ReadCloser, error) {
remoteRepo := getRemoteRepo(art)
log.Debugf("The blob doesn't exist, proxy the request to the target server, url:%v", remoteRepo)
rHelper, err := NewRemoteHelper(p.RegistryID)

View File

@ -17,12 +17,12 @@ package proxy
import (
"context"
"github.com/docker/distribution"
"github.com/goharbor/harbor/src/common/models"
"github.com/goharbor/harbor/src/controller/artifact"
"github.com/goharbor/harbor/src/controller/blob"
"github.com/goharbor/harbor/src/lib"
_ "github.com/goharbor/harbor/src/lib/cache"
"github.com/goharbor/harbor/src/lib/errors"
proModels "github.com/goharbor/harbor/src/pkg/project/models"
testproxy "github.com/goharbor/harbor/src/testing/controller/proxy"
"github.com/opencontainers/go-digest"
"github.com/stretchr/testify/mock"
@ -83,13 +83,13 @@ type proxyControllerTestSuite struct {
local *localInterfaceMock
remote *testproxy.RemoteInterface
ctr Controller
proj *models.Project
proj *proModels.Project
}
func (p *proxyControllerTestSuite) SetupTest() {
p.local = &localInterfaceMock{}
p.remote = &testproxy.RemoteInterface{}
p.proj = &models.Project{RegistryID: 1}
p.proj = &proModels.Project{RegistryID: 1}
p.ctr = &controller{
blobCtl: blob.Ctl,
artifactCtl: artifact.Ctl,

View File

@ -19,10 +19,10 @@ import (
"fmt"
"github.com/goharbor/harbor/src/lib/config"
"github.com/goharbor/harbor/src/pkg/config/db"
proModels "github.com/goharbor/harbor/src/pkg/project/models"
"strconv"
"github.com/goharbor/harbor/src/common"
"github.com/goharbor/harbor/src/common/models"
"github.com/goharbor/harbor/src/controller/blob"
"github.com/goharbor/harbor/src/lib/log"
dr "github.com/goharbor/harbor/src/pkg/quota/driver"
@ -68,7 +68,7 @@ func (d *driver) Load(ctx context.Context, key string) (dr.RefObject, error) {
return nil, err
}
project, ok := result.(*models.Project)
project, ok := result.(*proModels.Project)
if !ok {
return nil, fmt.Errorf("bad result for project: %s", key)
}

View File

@ -16,6 +16,7 @@ package project
import (
"context"
proModels "github.com/goharbor/harbor/src/pkg/project/models"
"strconv"
"github.com/goharbor/harbor/src/common/models"
@ -50,7 +51,7 @@ func getProjectsBatchFn(ctx context.Context, keys dataloader.Keys) []*dataloader
}
var ownerIDs []interface{}
var projectsMap = make(map[int64]*models.Project, len(projectIDs))
var projectsMap = make(map[int64]*proModels.Project, len(projectIDs))
for _, project := range projects {
ownerIDs = append(ownerIDs, project.OwnerID)
projectsMap[project.ProjectID] = project

View File

@ -16,11 +16,11 @@ package quota
import (
"context"
proModels "github.com/goharbor/harbor/src/pkg/project/models"
"math/rand"
"testing"
"time"
"github.com/goharbor/harbor/src/common/models"
"github.com/goharbor/harbor/src/controller/project"
"github.com/goharbor/harbor/src/lib/orm"
"github.com/goharbor/harbor/src/lib/q"
@ -76,21 +76,21 @@ func (suite *RefreshForProjectsTestSuite) TestRefreshForProjects() {
rand.Seed(time.Now().UnixNano())
startProjectID := rand.Int63()
var firstPageProjects, secondPageProjects []*models.Project
var firstPageProjects, secondPageProjects []*proModels.Project
for i := 0; i < 50; i++ {
firstPageProjects = append(firstPageProjects, &models.Project{
firstPageProjects = append(firstPageProjects, &proModels.Project{
ProjectID: startProjectID + int64(i),
})
}
for i := 0; i < 10; i++ {
secondPageProjects = append(secondPageProjects, &models.Project{
secondPageProjects = append(secondPageProjects, &proModels.Project{
ProjectID: startProjectID + 50 + int64(i),
})
}
page := 1
mock.OnAnything(suite.projectCtl, "List").Return(func(context.Context, *q.Query, ...project.Option) []*models.Project {
mock.OnAnything(suite.projectCtl, "List").Return(func(context.Context, *q.Query, ...project.Option) []*proModels.Project {
defer func() {
page++
}()

View File

@ -15,9 +15,9 @@
package repository
import (
proModels "github.com/goharbor/harbor/src/pkg/project/models"
"testing"
"github.com/goharbor/harbor/src/common/models"
"github.com/goharbor/harbor/src/controller/artifact"
"github.com/goharbor/harbor/src/lib/errors"
"github.com/goharbor/harbor/src/lib/orm"
@ -71,7 +71,7 @@ func (c *controllerTestSuite) TestEnsure() {
// doesn't exist
c.repoMgr.On("GetByName", mock.Anything, mock.Anything).Return(nil, errors.NotFoundError(nil))
c.proMgr.On("Get", mock.AnythingOfType("*context.valueCtx"), "library").Return(&models.Project{
c.proMgr.On("Get", mock.AnythingOfType("*context.valueCtx"), "library").Return(&proModels.Project{
ProjectID: 1,
}, nil)
c.repoMgr.On("Create", mock.Anything, mock.Anything).Return(int64(1), nil)

View File

@ -4,12 +4,12 @@ import (
"context"
"github.com/aliyun/alibaba-cloud-sdk-go/sdk/utils"
"github.com/goharbor/harbor/src/common"
"github.com/goharbor/harbor/src/common/models"
"github.com/goharbor/harbor/src/common/utils/test"
"github.com/goharbor/harbor/src/lib/config"
"github.com/goharbor/harbor/src/lib/q"
_ "github.com/goharbor/harbor/src/pkg/config/inmemory"
"github.com/goharbor/harbor/src/pkg/permission/types"
proModels "github.com/goharbor/harbor/src/pkg/project/models"
rbac_model "github.com/goharbor/harbor/src/pkg/rbac/model"
"github.com/goharbor/harbor/src/pkg/robot/model"
htesting "github.com/goharbor/harbor/src/testing"
@ -33,7 +33,7 @@ func (suite *ControllerTestSuite) TestGet() {
c := controller{robotMgr: robotMgr, rbacMgr: rbacMgr, proMgr: projectMgr}
ctx := context.TODO()
projectMgr.On("Get", mock.Anything, mock.Anything).Return(&models.Project{ProjectID: 1, Name: "library"}, nil)
projectMgr.On("Get", mock.Anything, mock.Anything).Return(&proModels.Project{ProjectID: 1, Name: "library"}, nil)
robotMgr.On("Get", mock.Anything, mock.Anything).Return(&model.Robot{
Name: "library+test",
Description: "test get method",
@ -101,7 +101,7 @@ func (suite *ControllerTestSuite) TestCreate() {
c := controller{robotMgr: robotMgr, rbacMgr: rbacMgr, proMgr: projectMgr}
ctx := context.TODO()
projectMgr.On("Get", mock.Anything, mock.Anything).Return(&models.Project{ProjectID: 1, Name: "library"}, nil)
projectMgr.On("Get", mock.Anything, mock.Anything).Return(&proModels.Project{ProjectID: 1, Name: "library"}, nil)
robotMgr.On("Create", mock.Anything, mock.Anything).Return(int64(1), nil)
rbacMgr.On("CreateRbacPolicy", mock.Anything, mock.Anything, mock.Anything).Return(int64(1), nil)
rbacMgr.On("CreatePermission", mock.Anything, mock.Anything, mock.Anything).Return(int64(1), nil)
@ -164,7 +164,7 @@ func (suite *ControllerTestSuite) TestUpdate() {
config.InitWithSettings(conf)
robotMgr.On("Update", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(nil)
projectMgr.On("Get", mock.Anything, mock.Anything).Return(&models.Project{ProjectID: 1, Name: "library"}, nil)
projectMgr.On("Get", mock.Anything, mock.Anything).Return(&proModels.Project{ProjectID: 1, Name: "library"}, nil)
rbacMgr.On("DeletePermissionsByRole", mock.Anything, mock.Anything, mock.Anything).Return(nil)
rbacMgr.On("CreateRbacPolicy", mock.Anything, mock.Anything, mock.Anything).Return(int64(1), nil)
@ -208,7 +208,7 @@ func (suite *ControllerTestSuite) TestList() {
c := controller{robotMgr: robotMgr, rbacMgr: rbacMgr, proMgr: projectMgr}
ctx := context.TODO()
projectMgr.On("Get", mock.Anything, mock.Anything).Return(&models.Project{ProjectID: 1, Name: "library"}, nil)
projectMgr.On("Get", mock.Anything, mock.Anything).Return(&proModels.Project{ProjectID: 1, Name: "library"}, nil)
robotMgr.On("List", mock.Anything, mock.Anything).Return([]*model.Robot{
{
Name: "test",
@ -233,7 +233,7 @@ func (suite *ControllerTestSuite) TestList() {
Action: "push",
},
}, nil)
projectMgr.On("Get", mock.Anything, mock.Anything).Return(&models.Project{ProjectID: 1, Name: "library"}, nil)
projectMgr.On("Get", mock.Anything, mock.Anything).Return(&proModels.Project{ProjectID: 1, Name: "library"}, nil)
rs, err := c.List(ctx, &q.Query{
Keywords: map[string]interface{}{
"name": "test3",
@ -257,7 +257,7 @@ func (suite *ControllerTestSuite) TestToScope() {
c := controller{robotMgr: robotMgr, rbacMgr: rbacMgr, proMgr: projectMgr}
ctx := context.TODO()
projectMgr.On("Get", mock.Anything, mock.Anything).Return(&models.Project{ProjectID: 1, Name: "library"}, nil)
projectMgr.On("Get", mock.Anything, mock.Anything).Return(&proModels.Project{ProjectID: 1, Name: "library"}, nil)
p := &Permission{
Kind: "system",

View File

@ -3,6 +3,7 @@ package api
import (
"errors"
"fmt"
proModels "github.com/goharbor/harbor/src/pkg/project/models"
"github.com/goharbor/harbor/src/common"
"github.com/goharbor/harbor/src/common/models"
@ -18,7 +19,7 @@ const (
// ChartLabelAPI handles the requests of marking/removing labels to/from charts.
type ChartLabelAPI struct {
LabelResourceAPI
project *models.Project
project *proModels.Project
chartFullName string
}

View File

@ -3,13 +3,13 @@ package api
import (
"context"
"errors"
proModels "github.com/goharbor/harbor/src/pkg/project/models"
"net/http"
"net/http/httptest"
"testing"
bcontext "github.com/astaxie/beego/context"
"github.com/goharbor/harbor/src/chartserver"
"github.com/goharbor/harbor/src/common/models"
projecttesting "github.com/goharbor/harbor/src/testing/controller/project"
"github.com/goharbor/harbor/src/testing/mock"
)
@ -42,7 +42,7 @@ func TestRequireNamespace(t *testing.T) {
projectCtl := &projecttesting.Controller{}
chartAPI.ProjectCtl = projectCtl
mock.OnAnything(projectCtl, "List").Return([]*models.Project{
mock.OnAnything(projectCtl, "List").Return([]*proModels.Project{
{ProjectID: 0, Name: "library"},
{ProjectID: 1, Name: "repo2"},
}, nil)

View File

@ -19,6 +19,21 @@ import (
"bytes"
"encoding/json"
"fmt"
"github.com/astaxie/beego"
"github.com/dghubble/sling"
"github.com/goharbor/harbor/src/common/api"
"github.com/goharbor/harbor/src/common/dao"
"github.com/goharbor/harbor/src/common/job/test"
testutils "github.com/goharbor/harbor/src/common/utils/test"
_ "github.com/goharbor/harbor/src/core/auth/db"
_ "github.com/goharbor/harbor/src/core/auth/ldap"
"github.com/goharbor/harbor/src/lib/config"
libOrm "github.com/goharbor/harbor/src/lib/orm"
proModels "github.com/goharbor/harbor/src/pkg/project/models"
"github.com/goharbor/harbor/src/server/middleware"
"github.com/goharbor/harbor/src/server/middleware/orm"
"github.com/goharbor/harbor/src/server/middleware/security"
"github.com/goharbor/harbor/src/testing/apitests/apilib"
"io/ioutil"
"log"
"net/http"
@ -26,23 +41,6 @@ import (
"path/filepath"
"runtime"
"strconv"
"strings"
"github.com/astaxie/beego"
"github.com/dghubble/sling"
"github.com/goharbor/harbor/src/common/api"
"github.com/goharbor/harbor/src/common/dao"
"github.com/goharbor/harbor/src/common/job/test"
"github.com/goharbor/harbor/src/common/models"
testutils "github.com/goharbor/harbor/src/common/utils/test"
_ "github.com/goharbor/harbor/src/core/auth/db"
_ "github.com/goharbor/harbor/src/core/auth/ldap"
"github.com/goharbor/harbor/src/lib/config"
libOrm "github.com/goharbor/harbor/src/lib/orm"
"github.com/goharbor/harbor/src/server/middleware"
"github.com/goharbor/harbor/src/server/middleware/orm"
"github.com/goharbor/harbor/src/server/middleware/security"
"github.com/goharbor/harbor/src/testing/apitests/apilib"
)
const (
@ -298,7 +296,7 @@ func (a testapi) ProjectsGet(query *apilib.ProjectQuery, authInfo ...usrInfo) (i
// Update properties for a selected project.
func (a testapi) ProjectsPut(prjUsr usrInfo, projectID string,
project *models.Project) (int, error) {
project *proModels.Project) (int, error) {
path := "/api/projects/" + projectID
_sling := sling.New().Put(a.basePath).Path(path).BodyJSON(project)
@ -367,31 +365,6 @@ func (a testapi) GetProjectMembersByProID(prjUsr usrInfo, projectID string) (int
return httpStatusCode, successPayload, err
}
// Add project role member accompany with projectID
// func (a testapi) AddProjectMember(prjUsr usrInfo, projectID string, roles apilib.RoleParam) (int, int, error) {
func (a testapi) AddProjectMember(prjUsr usrInfo, projectID string, member *models.MemberReq) (int, int, error) {
_sling := sling.New().Post(a.basePath)
path := "/api/projects/" + projectID + "/members/"
_sling = _sling.Path(path)
_sling = _sling.BodyJSON(member)
httpStatusCode, header, _, err := request0(_sling, jsonAcceptHeader, prjUsr)
var memberID int
location := header.Get("Location")
if location != "" {
parts := strings.Split(location, "/")
if len(parts) > 0 {
i, err := strconv.Atoi(parts[len(parts)-1])
if err == nil {
memberID = i
}
}
}
return httpStatusCode, memberID, err
}
// Delete project role member accompany with projectID
func (a testapi) DeleteProjectMember(authInfo usrInfo, projectID string, memberID string) (int, error) {
_sling := sling.New().Delete(a.basePath)

View File

@ -14,6 +14,7 @@
package ldap
import (
"github.com/goharbor/harbor/src/pkg/project"
"os"
"testing"
@ -358,7 +359,7 @@ func TestSearchAndOnBoardUser(t *testing.T) {
func TestAddProjectMemberWithLdapUser(t *testing.T) {
memberMgr := member.Mgr
ctx := orm.Context()
currentProject, err := dao.GetProjectByName("member_test_01")
currentProject, err := project.Mgr.Get(ctx, "member_test_01")
if err != nil {
t.Errorf("Error occurred when GetProjectByName: %v", err)
}
@ -378,7 +379,7 @@ func TestAddProjectMemberWithLdapUser(t *testing.T) {
t.Errorf("Error occurred in AddOrUpdateProjectMember: pmid:%v", pmid)
}
currentProject, err = dao.GetProjectByName("member_test_02")
currentProject, err = project.Mgr.Get(ctx, "member_test_02")
if err != nil {
t.Errorf("Error occurred when GetProjectByName: %v", err)
}
@ -400,7 +401,7 @@ func TestAddProjectMemberWithLdapUser(t *testing.T) {
func TestAddProjectMemberWithLdapGroup(t *testing.T) {
memberMgr := member.Mgr
ctx := orm.Context()
currentProject, err := dao.GetProjectByName("member_test_01")
currentProject, err := project.Mgr.Get(ctx, "member_test_01")
if err != nil {
t.Errorf("Error occurred when GetProjectByName: %v", err)
}

View File

@ -25,6 +25,7 @@ import (
"github.com/goharbor/harbor/src/lib/orm"
_ "github.com/goharbor/harbor/src/pkg/config/db"
_ "github.com/goharbor/harbor/src/pkg/config/inmemory"
proModels "github.com/goharbor/harbor/src/pkg/project/models"
"io/ioutil"
"net/url"
"os"
@ -34,7 +35,6 @@ import (
jwt "github.com/dgrijalva/jwt-go"
"github.com/docker/distribution/registry/auth/token"
"github.com/goharbor/harbor/src/common/models"
"github.com/goharbor/harbor/src/common/rbac"
"github.com/goharbor/harbor/src/common/security"
"github.com/stretchr/testify/assert"
@ -247,7 +247,7 @@ func (f *fakeSecurityContext) Can(ctx context.Context, action rbac.Action, resou
return false
}
func (f *fakeSecurityContext) GetMyProjects() ([]*models.Project, error) {
func (f *fakeSecurityContext) GetMyProjects() ([]*proModels.Project, error) {
return nil, nil
}
func (f *fakeSecurityContext) GetProjectRoles(interface{}) []int {

View File

@ -15,11 +15,11 @@
package gc
import (
proModels "github.com/goharbor/harbor/src/pkg/project/models"
"os"
"testing"
"github.com/docker/distribution/manifest/schema2"
"github.com/goharbor/harbor/src/common/models"
commom_regctl "github.com/goharbor/harbor/src/common/registryctl"
"github.com/goharbor/harbor/src/controller/project"
"github.com/goharbor/harbor/src/jobservice/job"
@ -117,7 +117,7 @@ func (suite *gcTestSuite) TestRemoveUntaggedBlobs() {
logger := &mockjobservice.MockJobLogger{}
ctx.On("GetLogger").Return(logger)
mock.OnAnything(suite.projectCtl, "List").Return([]*models.Project{
mock.OnAnything(suite.projectCtl, "List").Return([]*proModels.Project{
{
ProjectID: 1234,
Name: "test GC",
@ -226,7 +226,7 @@ func (suite *gcTestSuite) TestRun() {
suite.artifactCtl.On("Delete").Return(nil)
suite.artrashMgr.On("Filter").Return([]model.ArtifactTrash{}, nil)
mock.OnAnything(suite.projectCtl, "List").Return([]*models.Project{
mock.OnAnything(suite.projectCtl, "List").Return([]*proModels.Project{
{
ProjectID: 12345,
Name: "test GC",
@ -301,7 +301,7 @@ func (suite *gcTestSuite) TestMark() {
},
}, nil)
mock.OnAnything(suite.projectCtl, "List").Return([]*models.Project{
mock.OnAnything(suite.projectCtl, "List").Return([]*proModels.Project{
{
ProjectID: 1234,
Name: "test GC",

View File

@ -1,6 +1,7 @@
package exporter
import (
proModels "github.com/goharbor/harbor/src/pkg/project/models"
"strconv"
"testing"
"time"
@ -27,8 +28,8 @@ var (
alice = models.User{Username: "alice", Password: "password", Email: "alice@test.com"}
bob = models.User{Username: "bob", Password: "password", Email: "bob@test.com"}
eve = models.User{Username: "eve", Password: "password", Email: "eve@test.com"}
testPro1 = models.Project{OwnerID: 1, Name: "test1", Metadata: map[string]string{"public": "true"}}
testPro2 = models.Project{OwnerID: 1, Name: "test2", Metadata: map[string]string{"public": "false"}}
testPro1 = proModels.Project{OwnerID: 1, Name: "test1", Metadata: map[string]string{"public": "true"}}
testPro2 = proModels.Project{OwnerID: 1, Name: "test2", Metadata: map[string]string{"public": "false"}}
rs1 = qtypes.ResourceList{qtypes.ResourceStorage: 100}
rs2 = qtypes.ResourceList{qtypes.ResourceStorage: 200}
repo1 = model.RepoRecord{Name: "repo1"}

View File

@ -70,7 +70,7 @@ func (d *dao) Create(ctx context.Context, project *models.Project) (int64, error
return orm.WrapConflictError(err, "The project named %s already exists", project.Name)
}
member := &Member{
member := &models.Member{
ProjectID: projectID,
EntityID: project.OwnerID,
Role: common.RoleProjectAdmin,
@ -170,7 +170,7 @@ func (d *dao) List(ctx context.Context, query *q.Query) ([]*models.Project, erro
}
func (d *dao) ListRoles(ctx context.Context, projectID int64, userID int, groupIDs ...int) ([]int, error) {
qs, err := orm.QuerySetter(ctx, &Member{}, nil)
qs, err := orm.QuerySetter(ctx, &models.Member{}, nil)
if err != nil {
return nil, err
}

View File

@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
package dao
package models
import (
"time"
@ -37,6 +37,16 @@ type Member struct {
UpdateTime time.Time `orm:"column(update_time);auto_now" json:"update_time"`
}
// MemberQuery ...
type MemberQuery struct {
UserID int // the user id
Name string // the username of member
Role int // the role of the member has to the project
GroupIDs []int // the group ID of current user belongs to
WithPublic bool // include the public projects for the member
}
// TableName ...
func (*Member) TableName() string {
return "project_member"

View File

@ -15,14 +15,192 @@
package models
import (
"github.com/goharbor/harbor/src/common/models"
"context"
"fmt"
"github.com/astaxie/beego/orm"
allowlist "github.com/goharbor/harbor/src/pkg/allowlist/models"
"github.com/lib/pq"
"strconv"
"strings"
"time"
)
// Project ...
type Project = models.Project
const (
// ProjectTable is the table name for project
ProjectTable = "project"
// ProjectPublic means project is public
ProjectPublic = "public"
// ProjectPrivate means project is private
ProjectPrivate = "private"
)
func init() {
orm.RegisterModel(&Project{})
}
// Project holds the details of a project.
type Project struct {
ProjectID int64 `orm:"pk;auto;column(project_id)" json:"project_id"`
OwnerID int `orm:"column(owner_id)" json:"owner_id"`
Name string `orm:"column(name)" json:"name" sort:"default"`
CreationTime time.Time `orm:"column(creation_time);auto_now_add" json:"creation_time"`
UpdateTime time.Time `orm:"column(update_time);auto_now" json:"update_time"`
Deleted bool `orm:"column(deleted)" json:"deleted"`
OwnerName string `orm:"-" json:"owner_name"`
Role int `orm:"-" json:"current_user_role_id"`
RoleList []int `orm:"-" json:"current_user_role_ids"`
RepoCount int64 `orm:"-" json:"repo_count"`
ChartCount uint64 `orm:"-" json:"chart_count"`
Metadata map[string]string `orm:"-" json:"metadata"`
CVEAllowlist allowlist.CVEAllowlist `orm:"-" json:"cve_allowlist"`
RegistryID int64 `orm:"column(registry_id)" json:"registry_id"`
}
// GetMetadata ...
func (p *Project) GetMetadata(key string) (string, bool) {
if len(p.Metadata) == 0 {
return "", false
}
value, exist := p.Metadata[key]
return value, exist
}
// SetMetadata ...
func (p *Project) SetMetadata(key, value string) {
if p.Metadata == nil {
p.Metadata = map[string]string{}
}
p.Metadata[key] = value
}
// IsPublic ...
func (p *Project) IsPublic() bool {
public, exist := p.GetMetadata(ProMetaPublic)
if !exist {
return false
}
return isTrue(public)
}
// IsProxy returns true when the project type is proxy cache
func (p *Project) IsProxy() bool {
return p.RegistryID > 0
}
// ContentTrustEnabled ...
func (p *Project) ContentTrustEnabled() bool {
enabled, exist := p.GetMetadata(ProMetaEnableContentTrust)
if !exist {
return false
}
return isTrue(enabled)
}
// VulPrevented ...
func (p *Project) VulPrevented() bool {
prevent, exist := p.GetMetadata(ProMetaPreventVul)
if !exist {
return false
}
return isTrue(prevent)
}
// ReuseSysCVEAllowlist ...
func (p *Project) ReuseSysCVEAllowlist() bool {
r, ok := p.GetMetadata(ProMetaReuseSysCVEAllowlist)
if !ok {
return true
}
return isTrue(r)
}
// Severity ...
func (p *Project) Severity() string {
severity, exist := p.GetMetadata(ProMetaSeverity)
if !exist {
return ""
}
return severity
}
// AutoScan ...
func (p *Project) AutoScan() bool {
auto, exist := p.GetMetadata(ProMetaAutoScan)
if !exist {
return false
}
return isTrue(auto)
}
// FilterByPublic returns orm.QuerySeter with public filter
func (p *Project) FilterByPublic(ctx context.Context, qs orm.QuerySeter, key string, value interface{}) orm.QuerySeter {
subQuery := `SELECT project_id FROM project_metadata WHERE name = 'public' AND value = '%s'`
if isTrue(value) {
subQuery = fmt.Sprintf(subQuery, "true")
} else {
subQuery = fmt.Sprintf(subQuery, "false")
}
return qs.FilterRaw("project_id", fmt.Sprintf("IN (%s)", subQuery))
}
// FilterByOwner returns orm.QuerySeter with owner filter
func (p *Project) FilterByOwner(ctx context.Context, qs orm.QuerySeter, key string, value interface{}) orm.QuerySeter {
username, ok := value.(string)
if !ok {
return qs
}
return qs.FilterRaw("owner_id", fmt.Sprintf("IN (SELECT user_id FROM harbor_user WHERE username = %s)", pq.QuoteLiteral(username)))
}
// FilterByMember returns orm.QuerySeter with member filter
func (p *Project) FilterByMember(ctx context.Context, qs orm.QuerySeter, key string, value interface{}) orm.QuerySeter {
query, ok := value.(*MemberQuery)
if !ok {
return qs
}
subQuery := fmt.Sprintf(`SELECT project_id FROM project_member WHERE entity_id = %d AND entity_type = 'u'`, query.UserID)
if query.Role > 0 {
subQuery = fmt.Sprintf("%s AND role = %d", subQuery, query.Role)
}
if query.WithPublic {
subQuery = fmt.Sprintf("(%s) UNION (SELECT project_id FROM project_metadata WHERE name = 'public' AND value = 'true')", subQuery)
}
if len(query.GroupIDs) > 0 {
var elems []string
for _, groupID := range query.GroupIDs {
elems = append(elems, strconv.Itoa(groupID))
}
tpl := "(%s) UNION (SELECT project_id FROM project_member pm, user_group ug WHERE pm.entity_id = ug.id AND pm.entity_type = 'g' AND ug.id IN (%s))"
subQuery = fmt.Sprintf(tpl, subQuery, strings.TrimSpace(strings.Join(elems, ", ")))
}
return qs.FilterRaw("project_id", fmt.Sprintf("IN (%s)", subQuery))
}
func isTrue(i interface{}) bool {
switch value := i.(type) {
case bool:
return value
case string:
v := strings.ToLower(value)
return v == "true" || v == "1"
default:
return false
}
}
// TableName is required by beego orm to map Project to table project
func (p *Project) TableName() string {
return ProjectTable
}
// Projects the connection for Project
type Projects []*models.Project
type Projects []*Project
// OwnerIDs returns all the owner ids from the projects
func (projects Projects) OwnerIDs() []int {
@ -32,9 +210,3 @@ func (projects Projects) OwnerIDs() []int {
}
return ownerIDs
}
// Member ...
type Member = models.Member
// MemberQuery ...
type MemberQuery = models.MemberQuery

View File

@ -17,10 +17,10 @@ package retention
import (
"context"
"github.com/goharbor/harbor/src/lib/orm"
proModels "github.com/goharbor/harbor/src/pkg/project/models"
"testing"
"github.com/goharbor/harbor/src/common/job"
"github.com/goharbor/harbor/src/common/models"
_ "github.com/goharbor/harbor/src/lib/selector/selectors/doublestar"
"github.com/goharbor/harbor/src/pkg/project"
"github.com/goharbor/harbor/src/pkg/repository/model"
@ -116,16 +116,16 @@ type launchTestSuite struct {
}
func (l *launchTestSuite) SetupTest() {
pro1 := &models.Project{
pro1 := &proModels.Project{
ProjectID: 1,
Name: "library",
}
pro2 := &models.Project{
pro2 := &proModels.Project{
ProjectID: 2,
Name: "test",
}
projectMgr := &projecttesting.Manager{}
mock.OnAnything(projectMgr, "List").Return([]*models.Project{
mock.OnAnything(projectMgr, "List").Return([]*proModels.Project{
pro1, pro2,
}, nil)
l.projectMgr = projectMgr

View File

@ -16,11 +16,11 @@ package contenttrust
import (
"fmt"
proModels "github.com/goharbor/harbor/src/pkg/project/models"
"net/http"
"net/http/httptest"
"testing"
"github.com/goharbor/harbor/src/common/models"
"github.com/goharbor/harbor/src/common/security"
"github.com/goharbor/harbor/src/controller/artifact"
"github.com/goharbor/harbor/src/controller/artifact/processor/image"
@ -43,7 +43,7 @@ type MiddlewareTestSuite struct {
projectController *projecttesting.Controller
artifact *artifact.Artifact
project *models.Project
project *proModels.Project
isArtifactSigned func(req *http.Request, art lib.ArtifactInfo) (bool, error)
next http.Handler
@ -65,11 +65,11 @@ func (suite *MiddlewareTestSuite) SetupTest() {
suite.artifact.RepositoryName = "library/photon"
suite.artifact.Digest = "digest"
suite.project = &models.Project{
suite.project = &proModels.Project{
ProjectID: suite.artifact.ProjectID,
Name: "library",
Metadata: map[string]string{
models.ProMetaEnableContentTrust: "true",
proModels.ProMetaEnableContentTrust: "true",
},
}
@ -121,7 +121,7 @@ func (suite *MiddlewareTestSuite) TestGetProjectFailed() {
func (suite *MiddlewareTestSuite) TestContentTrustDisabled() {
mock.OnAnything(suite.artifactController, "GetByReference").Return(suite.artifact, nil)
suite.project.Metadata[models.ProMetaEnableContentTrust] = "false"
suite.project.Metadata[proModels.ProMetaEnableContentTrust] = "false"
mock.OnAnything(suite.projectController, "GetByName").Return(suite.project, nil)
req := suite.makeRequest()

View File

@ -4,6 +4,8 @@ import (
"context"
"fmt"
"github.com/goharbor/harbor/src/controller/immutable"
"github.com/goharbor/harbor/src/pkg/project"
proModels "github.com/goharbor/harbor/src/pkg/project/models"
"math/rand"
"net/http"
"net/http/httptest"
@ -12,7 +14,6 @@ import (
"time"
"github.com/goharbor/harbor/src/common/dao"
"github.com/goharbor/harbor/src/common/models"
"github.com/goharbor/harbor/src/lib"
internal_orm "github.com/goharbor/harbor/src/lib/orm"
"github.com/goharbor/harbor/src/pkg/artifact"
@ -71,8 +72,8 @@ func randomString(n int) string {
return string(b)
}
func (suite *HandlerSuite) addProject(projectName string) int64 {
projectID, err := dao.AddProject(models.Project{
func (suite *HandlerSuite) addProject(ctx context.Context, projectName string) int64 {
projectID, err := project.Mgr.Create(ctx, &proModels.Project{
Name: projectName,
OwnerID: 1,
})
@ -153,14 +154,14 @@ func (suite *HandlerSuite) TestPutDeleteManifestCreated() {
dgt := digest.FromString(randomString(15)).String()
ctx := internal_orm.NewContext(context.TODO(), dao.GetOrmer())
projectID := suite.addProject(projectName)
projectID := suite.addProject(ctx, projectName)
immuRuleID := suite.addImmutableRule(projectID)
repoID := suite.addRepo(ctx, projectID, repoName)
afID := suite.addArt(ctx, projectID, repoID, repoName, dgt)
tagID := suite.addTags(ctx, repoID, afID, "release-1.10")
defer func() {
dao.DeleteProject(projectID)
project.Mgr.Delete(ctx, projectID)
artifact.Mgr.Delete(ctx, afID)
repository.Mgr.Delete(ctx, repoID)
tag.Mgr.Delete(ctx, tagID)

View File

@ -29,11 +29,11 @@
package quota
import (
proModels "github.com/goharbor/harbor/src/pkg/project/models"
"net/http"
"net/http/httptest"
"testing"
commonmodels "github.com/goharbor/harbor/src/common/models"
"github.com/goharbor/harbor/src/controller/artifact"
"github.com/goharbor/harbor/src/pkg/notification"
"github.com/goharbor/harbor/src/pkg/quota"
@ -84,7 +84,7 @@ func (suite *CopyArtifactMiddlewareTestSuite) SetupTest() {
walkFn(suite.artifact)
})
mock.OnAnything(suite.projectController, "Get").Return(&commonmodels.Project{}, nil)
mock.OnAnything(suite.projectController, "Get").Return(&proModels.Project{}, nil)
}
func (suite *CopyArtifactMiddlewareTestSuite) TestResourcesWarning() {

View File

@ -16,12 +16,12 @@ package quota
import (
"fmt"
proModels "github.com/goharbor/harbor/src/pkg/project/models"
"net/http"
"net/http/httptest"
"strconv"
"testing"
commonmodels "github.com/goharbor/harbor/src/common/models"
"github.com/goharbor/harbor/src/lib/errors"
"github.com/goharbor/harbor/src/pkg/notification"
"github.com/goharbor/harbor/src/pkg/quota"
@ -118,7 +118,7 @@ func (suite *PutBlobUploadMiddlewareTestSuite) TestBlobExistFailed() {
func (suite *PutBlobUploadMiddlewareTestSuite) TestResourcesExceeded() {
mock.OnAnything(suite.quotaController, "IsEnabled").Return(true, nil)
mock.OnAnything(suite.blobController, "Exist").Return(false, nil)
mock.OnAnything(suite.projectController, "Get").Return(&commonmodels.Project{}, nil)
mock.OnAnything(suite.projectController, "Get").Return(&proModels.Project{}, nil)
{
var errs quota.Errors

View File

@ -17,13 +17,13 @@ package quota
import (
"context"
std_err "errors"
proModels "github.com/goharbor/harbor/src/pkg/project/models"
"net/http"
"net/http/httptest"
"strings"
"testing"
"github.com/docker/distribution/manifest/schema2"
commonmodels "github.com/goharbor/harbor/src/common/models"
"github.com/goharbor/harbor/src/lib/errors"
"github.com/goharbor/harbor/src/pkg/blob/models"
"github.com/goharbor/harbor/src/pkg/distribution"
@ -187,7 +187,7 @@ func (suite *PutManifestMiddlewareTestSuite) TestResourcesExceeded() {
mock.OnAnything(suite.quotaController, "IsEnabled").Return(true, nil)
mock.OnAnything(suite.blobController, "Exist").Return(false, nil)
mock.OnAnything(suite.blobController, "FindMissingAssociationsForProject").Return(nil, nil)
mock.OnAnything(suite.projectController, "Get").Return(&commonmodels.Project{}, nil)
mock.OnAnything(suite.projectController, "Get").Return(&proModels.Project{}, nil)
next := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
@ -235,7 +235,7 @@ func (suite *PutManifestMiddlewareTestSuite) TestResourcesWarning() {
f := args.Get(4).(func() error)
f()
})
mock.OnAnything(suite.projectController, "Get").Return(&commonmodels.Project{}, nil)
mock.OnAnything(suite.projectController, "Get").Return(&proModels.Project{}, nil)
next := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)

View File

@ -16,11 +16,11 @@ package quota
import (
"fmt"
proModels "github.com/goharbor/harbor/src/pkg/project/models"
"net/http"
"net/http/httptest"
"testing"
"github.com/goharbor/harbor/src/common/models"
"github.com/goharbor/harbor/src/controller/artifact"
"github.com/goharbor/harbor/src/controller/blob"
"github.com/goharbor/harbor/src/controller/project"
@ -64,7 +64,7 @@ func (suite *RequestMiddlewareTestSuite) SetupTest() {
suite.projectController = &projecttesting.Controller{}
projectController = suite.projectController
mock.OnAnything(suite.projectController, "GetByName").Return(&models.Project{ProjectID: 1, Name: "library"}, nil)
mock.OnAnything(suite.projectController, "GetByName").Return(&proModels.Project{ProjectID: 1, Name: "library"}, nil)
suite.originallQuotaController = quotaController
suite.quotaController = &quotatesting.Controller{}

View File

@ -17,18 +17,18 @@ package quota
import (
"context"
"fmt"
proModels "github.com/goharbor/harbor/src/pkg/project/models"
"net/http"
"net/http/httptest"
"testing"
"github.com/goharbor/harbor/src/common/models"
"github.com/goharbor/harbor/src/testing/controller/project"
"github.com/stretchr/testify/mock"
)
func Test_projectReferenceObject(t *testing.T) {
ctl := &project.Controller{}
ctl.On("GetByName", mock.AnythingOfType(""), "library").Return(&models.Project{ProjectID: 1}, nil)
ctl.On("GetByName", mock.AnythingOfType(""), "library").Return(&proModels.Project{ProjectID: 1}, nil)
ctl.On("GetByName", mock.AnythingOfType(""), "demo").Return(nil, fmt.Errorf("not found"))
originalProjectController := projectController

View File

@ -17,7 +17,6 @@ package repoproxy
import (
"context"
"fmt"
"github.com/goharbor/harbor/src/common/models"
"github.com/goharbor/harbor/src/common/security"
"github.com/goharbor/harbor/src/common/security/proxycachesecret"
"github.com/goharbor/harbor/src/controller/project"
@ -28,6 +27,7 @@ import (
httpLib "github.com/goharbor/harbor/src/lib/http"
"github.com/goharbor/harbor/src/lib/log"
"github.com/goharbor/harbor/src/lib/orm"
proModels "github.com/goharbor/harbor/src/pkg/project/models"
"github.com/goharbor/harbor/src/pkg/reg/model"
"github.com/goharbor/harbor/src/server/middleware"
"io"
@ -80,7 +80,7 @@ func handleBlob(w http.ResponseWriter, r *http.Request, next http.Handler) error
return nil
}
func preCheck(ctx context.Context) (art lib.ArtifactInfo, p *models.Project, ctl proxy.Controller, err error) {
func preCheck(ctx context.Context) (art lib.ArtifactInfo, p *proModels.Project, ctl proxy.Controller, err error) {
none := lib.ArtifactInfo{}
art = lib.GetArtifactInfo(ctx)
if art == none {
@ -152,7 +152,7 @@ func handleManifest(w http.ResponseWriter, r *http.Request, next http.Handler) e
return nil
}
func proxyManifestGet(ctx context.Context, w http.ResponseWriter, ctl proxy.Controller, p *models.Project, art lib.ArtifactInfo, remote proxy.RemoteInterface) error {
func proxyManifestGet(ctx context.Context, w http.ResponseWriter, ctl proxy.Controller, p *proModels.Project, art lib.ArtifactInfo, remote proxy.RemoteInterface) error {
man, err := ctl.ProxyManifest(ctx, art, remote)
if err != nil {
return err
@ -168,7 +168,7 @@ func proxyManifestGet(ctx context.Context, w http.ResponseWriter, ctl proxy.Cont
return nil
}
func canProxy(p *models.Project) bool {
func canProxy(p *proModels.Project) bool {
if p.RegistryID < 1 {
return false
}
@ -227,7 +227,7 @@ func DisableBlobAndManifestUploadMiddleware() func(http.Handler) http.Handler {
})
}
func proxyManifestHead(ctx context.Context, w http.ResponseWriter, ctl proxy.Controller, p *models.Project, art lib.ArtifactInfo, remote proxy.RemoteInterface) error {
func proxyManifestHead(ctx context.Context, w http.ResponseWriter, ctl proxy.Controller, p *proModels.Project, art lib.ArtifactInfo, remote proxy.RemoteInterface) error {
exist, desc, err := ctl.HeadManifest(ctx, art, remote)
if err != nil {
return err

View File

@ -19,6 +19,7 @@ import (
"fmt"
testutils "github.com/goharbor/harbor/src/common/utils/test"
"github.com/goharbor/harbor/src/lib/config"
proModels "github.com/goharbor/harbor/src/pkg/project/models"
"net/http"
"net/http/httptest"
@ -28,7 +29,6 @@ import (
"testing"
"github.com/goharbor/harbor/src/common"
"github.com/goharbor/harbor/src/common/models"
"github.com/goharbor/harbor/src/common/rbac"
"github.com/goharbor/harbor/src/common/security"
"github.com/goharbor/harbor/src/controller/project"
@ -46,20 +46,20 @@ func TestMain(m *testing.M) {
ctl := &projecttesting.Controller{}
mockGet := func(ctx context.Context,
projectIDOrName interface{}, options ...project.Option) (*models.Project, error) {
projectIDOrName interface{}, options ...project.Option) (*proModels.Project, error) {
name := projectIDOrName.(string)
id, _ := strconv.Atoi(strings.TrimPrefix(name, "project_"))
if id == 0 {
return nil, fmt.Errorf("%s not found", name)
}
return &models.Project{
return &proModels.Project{
ProjectID: int64(id),
Name: name,
}, nil
}
mock.OnAnything(ctl, "Get").Return(
func(ctx context.Context,
projectIDOrName interface{}, options ...project.Option) *models.Project {
projectIDOrName interface{}, options ...project.Option) *proModels.Project {
p, _ := mockGet(ctx, projectIDOrName, options...)
return p
},

View File

@ -16,12 +16,12 @@ package vulnerable
import (
"fmt"
proModels "github.com/goharbor/harbor/src/pkg/project/models"
"net/http"
"net/http/httptest"
"testing"
"github.com/docker/distribution/manifest/manifestlist"
"github.com/goharbor/harbor/src/common/models"
"github.com/goharbor/harbor/src/common/security"
"github.com/goharbor/harbor/src/controller/artifact"
"github.com/goharbor/harbor/src/controller/artifact/processor/image"
@ -54,7 +54,7 @@ type MiddlewareTestSuite struct {
scanChecker func() scan.Checker
artifact *artifact.Artifact
project *models.Project
project *proModels.Project
next http.Handler
}
@ -85,12 +85,12 @@ func (suite *MiddlewareTestSuite) SetupTest() {
suite.artifact.RepositoryName = "library/photon"
suite.artifact.Digest = "digest"
suite.project = &models.Project{
suite.project = &proModels.Project{
ProjectID: suite.artifact.ProjectID,
Name: "library",
Metadata: map[string]string{
models.ProMetaPreventVul: "true",
models.ProMetaSeverity: vuln.High.String(),
proModels.ProMetaPreventVul: "true",
proModels.ProMetaSeverity: vuln.High.String(),
},
}
@ -153,7 +153,7 @@ func (suite *MiddlewareTestSuite) TestGetProjectFailed() {
func (suite *MiddlewareTestSuite) TestPreventionDisabled() {
mock.OnAnything(suite.artifactController, "GetByReference").Return(suite.artifact, nil)
suite.project.Metadata[models.ProMetaPreventVul] = "false"
suite.project.Metadata[proModels.ProMetaPreventVul] = "false"
mock.OnAnything(suite.projectController, "Get").Return(suite.project, nil)
req := suite.makeRequest()

View File

@ -17,11 +17,11 @@ package handler
import (
"context"
"github.com/go-openapi/runtime/middleware"
"github.com/goharbor/harbor/src/common/models"
"github.com/goharbor/harbor/src/common/rbac"
"github.com/goharbor/harbor/src/controller/project"
"github.com/goharbor/harbor/src/controller/project/metadata"
"github.com/goharbor/harbor/src/lib/errors"
proModels "github.com/goharbor/harbor/src/pkg/project/models"
"github.com/goharbor/harbor/src/pkg/scan/vuln"
operation "github.com/goharbor/harbor/src/server/v2.0/restapi/operations/project_metadata"
"strconv"
@ -140,19 +140,19 @@ func (p *projectMetadataAPI) validate(metas map[string]string) (map[string]strin
}
switch key {
case models.ProMetaPublic, models.ProMetaEnableContentTrust,
models.ProMetaPreventVul, models.ProMetaAutoScan:
case proModels.ProMetaPublic, proModels.ProMetaEnableContentTrust,
proModels.ProMetaPreventVul, proModels.ProMetaAutoScan:
v, err := strconv.ParseBool(value)
if err != nil {
return nil, errors.New(nil).WithCode(errors.BadRequestCode).WithMessage("invalid value: %s", value)
}
metas[key] = strconv.FormatBool(v)
case models.ProMetaSeverity:
case proModels.ProMetaSeverity:
severity := vuln.ParseSeverityVersion3(strings.ToLower(value))
if severity == vuln.Unknown {
return nil, errors.New(nil).WithCode(errors.BadRequestCode).WithMessage("invalid value: %s", value)
}
metas[models.ProMetaSeverity] = strings.ToLower(severity.String())
metas[proModels.ProMetaSeverity] = strings.ToLower(severity.String())
default:
return nil, errors.New(nil).WithCode(errors.BadRequestCode).WithMessage("invalid key: %s", key)
}

View File

@ -23,13 +23,13 @@
package apilib
import (
"github.com/goharbor/harbor/src/common/models"
proModels "github.com/goharbor/harbor/src/pkg/project/models"
)
type Search struct {
// Search results of the projects that matched the filter keywords.
Projects []models.Project `json:"project,omitempty"`
Projects []proModels.Project `json:"project,omitempty"`
// Search results of the repositories that matched the filter keywords.
Repositories []SearchRepository `json:"repository,omitempty"`

View File

@ -5,9 +5,12 @@ package project
import (
context "context"
models "github.com/goharbor/harbor/src/common/models"
commonmodels "github.com/goharbor/harbor/src/common/models"
mock "github.com/stretchr/testify/mock"
models "github.com/goharbor/harbor/src/pkg/project/models"
project "github.com/goharbor/harbor/src/controller/project"
q "github.com/goharbor/harbor/src/lib/q"
@ -186,11 +189,11 @@ func (_m *Controller) List(ctx context.Context, query *q.Query, options ...proje
}
// ListRoles provides a mock function with given fields: ctx, projectID, u
func (_m *Controller) ListRoles(ctx context.Context, projectID int64, u *models.User) ([]int, error) {
func (_m *Controller) ListRoles(ctx context.Context, projectID int64, u *commonmodels.User) ([]int, error) {
ret := _m.Called(ctx, projectID, u)
var r0 []int
if rf, ok := ret.Get(0).(func(context.Context, int64, *models.User) []int); ok {
if rf, ok := ret.Get(0).(func(context.Context, int64, *commonmodels.User) []int); ok {
r0 = rf(ctx, projectID, u)
} else {
if ret.Get(0) != nil {
@ -199,7 +202,7 @@ func (_m *Controller) ListRoles(ctx context.Context, projectID int64, u *models.
}
var r1 error
if rf, ok := ret.Get(1).(func(context.Context, int64, *models.User) error); ok {
if rf, ok := ret.Get(1).(func(context.Context, int64, *commonmodels.User) error); ok {
r1 = rf(ctx, projectID, u)
} else {
r1 = ret.Error(1)

View File

@ -5,7 +5,7 @@ package project
import (
context "context"
models "github.com/goharbor/harbor/src/common/models"
models "github.com/goharbor/harbor/src/pkg/project/models"
mock "github.com/stretchr/testify/mock"
q "github.com/goharbor/harbor/src/lib/q"

View File

@ -16,7 +16,10 @@ package testing
import (
"context"
"fmt"
"github.com/goharbor/harbor/src/common"
"github.com/goharbor/harbor/src/lib/config"
proModels "github.com/goharbor/harbor/src/pkg/project/models"
"io"
"math/rand"
"net/http"
@ -26,7 +29,6 @@ import (
o "github.com/astaxie/beego/orm"
"github.com/goharbor/harbor/src/common/dao"
"github.com/goharbor/harbor/src/common/models"
"github.com/goharbor/harbor/src/lib/errors"
"github.com/goharbor/harbor/src/lib/orm"
"github.com/opencontainers/go-digest"
@ -101,7 +103,9 @@ func (suite *Suite) WithProject(f func(int64, string), projectNames ...string) {
projectName = suite.RandString(5)
}
projectID, err := dao.AddProject(models.Project{
ctx := suite.Context()
projectID, err := suite.AddProject(ctx, &proModels.Project{
Name: projectName,
OwnerID: 1,
})
@ -110,7 +114,7 @@ func (suite *Suite) WithProject(f func(int64, string), projectNames ...string) {
}
defer func() {
dao.DeleteProject(projectID)
suite.DeleteProject(ctx, projectName, projectID)
}()
f(projectID, projectName)
@ -158,3 +162,60 @@ func (suite *Suite) ExecSQL(query string, args ...interface{}) {
func (suite *Suite) IsNotFoundErr(err error) bool {
return suite.True(errors.IsNotFoundErr(err))
}
// AddProject put here is to avoid import cycle
func (suite *Suite) AddProject(ctx context.Context, project *proModels.Project) (int64, error) {
// Create create a project instance
var projectID int64
h := func(ctx context.Context) error {
o, err := orm.FromContext(ctx)
if err != nil {
return err
}
now := time.Now()
project.CreationTime = now
project.UpdateTime = now
projectID, err = o.Insert(project)
if err != nil {
return orm.WrapConflictError(err, "The project named %s already exists", project.Name)
}
member := &proModels.Member{
ProjectID: projectID,
EntityID: project.OwnerID,
Role: common.RoleProjectAdmin,
EntityType: common.UserMember,
CreationTime: now,
UpdateTime: now,
}
if _, err := o.Insert(member); err != nil {
return err
}
return nil
}
if err := orm.WithTransaction(h)(ctx); err != nil {
return 0, err
}
return projectID, nil
}
// DeleteProject put here is to avoid import cycle
func (suite *Suite) DeleteProject(ctx context.Context, projectName string, projectID int64) error {
o, err := orm.FromContext(ctx)
if err != nil {
return err
}
name := fmt.Sprintf("%s#%d", projectName, projectID)
sql := `update project
set deleted = true, name = ?
where project_id = ?`
_, err = o.Raw(sql, name, projectID).Exec()
return err
}