summaryrefslogtreecommitdiffstats
path: root/models
diff options
context:
space:
mode:
Diffstat (limited to 'models')
-rw-r--r--models/lfs.go80
-rw-r--r--models/repo_list.go48
2 files changed, 103 insertions, 25 deletions
diff --git a/models/lfs.go b/models/lfs.go
index 9b20642777..5f5fe2ccf4 100644
--- a/models/lfs.go
+++ b/models/lfs.go
@@ -8,6 +8,8 @@ import (
"io"
"code.gitea.io/gitea/modules/timeutil"
+
+ "xorm.io/builder"
)
// LFSMetaObject stores metadata for LFS tracked files.
@@ -106,19 +108,91 @@ func (repo *Repository) GetLFSMetaObjectByOid(oid string) (*LFSMetaObject, error
// RemoveLFSMetaObjectByOid removes a LFSMetaObject entry from database by its OID.
// It may return ErrLFSObjectNotExist or a database error.
-func (repo *Repository) RemoveLFSMetaObjectByOid(oid string) error {
+func (repo *Repository) RemoveLFSMetaObjectByOid(oid string) (int64, error) {
if len(oid) == 0 {
- return ErrLFSObjectNotExist
+ return 0, ErrLFSObjectNotExist
}
sess := x.NewSession()
defer sess.Close()
if err := sess.Begin(); err != nil {
- return err
+ return -1, err
}
m := &LFSMetaObject{Oid: oid, RepositoryID: repo.ID}
if _, err := sess.Delete(m); err != nil {
+ return -1, err
+ }
+
+ count, err := sess.Count(&LFSMetaObject{Oid: oid})
+ if err != nil {
+ return count, err
+ }
+
+ return count, sess.Commit()
+}
+
+// GetLFSMetaObjects returns all LFSMetaObjects associated with a repository
+func (repo *Repository) GetLFSMetaObjects(page, pageSize int) ([]*LFSMetaObject, error) {
+ sess := x.NewSession()
+ defer sess.Close()
+
+ if page >= 0 && pageSize > 0 {
+ start := 0
+ if page > 0 {
+ start = (page - 1) * pageSize
+ }
+ sess.Limit(pageSize, start)
+ }
+ lfsObjects := make([]*LFSMetaObject, 0, pageSize)
+ return lfsObjects, sess.Find(&lfsObjects, &LFSMetaObject{RepositoryID: repo.ID})
+}
+
+// CountLFSMetaObjects returns a count of all LFSMetaObjects associated with a repository
+func (repo *Repository) CountLFSMetaObjects() (int64, error) {
+ return x.Count(&LFSMetaObject{RepositoryID: repo.ID})
+}
+
+// LFSObjectAccessible checks if a provided Oid is accessible to the user
+func LFSObjectAccessible(user *User, oid string) (bool, error) {
+ if user.IsAdmin {
+ count, err := x.Count(&LFSMetaObject{Oid: oid})
+ return (count > 0), err
+ }
+ cond := accessibleRepositoryCondition(user.ID)
+ count, err := x.Where(cond).Join("INNER", "repository", "`lfs_meta_object`.repository_id = `repository`.id").Count(&LFSMetaObject{Oid: oid})
+ return (count > 0), err
+}
+
+// LFSAutoAssociate auto associates accessible LFSMetaObjects
+func LFSAutoAssociate(metas []*LFSMetaObject, user *User, repoID int64) error {
+ sess := x.NewSession()
+ defer sess.Close()
+ if err := sess.Begin(); err != nil {
+ return err
+ }
+
+ oids := make([]interface{}, len(metas))
+ oidMap := make(map[string]*LFSMetaObject, len(metas))
+ for i, meta := range metas {
+ oids[i] = meta.Oid
+ oidMap[meta.Oid] = meta
+ }
+
+ cond := builder.NewCond()
+ if !user.IsAdmin {
+ cond = builder.In("`lfs_meta_object`.repository_id",
+ builder.Select("`repository`.id").From("repository").Where(accessibleRepositoryCondition(user.ID)))
+ }
+ newMetas := make([]*LFSMetaObject, 0, len(metas))
+ if err := sess.Cols("oid").Where(cond).In("oid", oids...).GroupBy("oid").Find(&newMetas); err != nil {
+ return err
+ }
+ for i := range newMetas {
+ newMetas[i].Size = oidMap[newMetas[i].Oid].Size
+ newMetas[i].RepositoryID = repoID
+ }
+ if _, err := sess.InsertMulti(newMetas); err != nil {
return err
}
diff --git a/models/repo_list.go b/models/repo_list.go
index 692d4d002f..c823647eba 100644
--- a/models/repo_list.go
+++ b/models/repo_list.go
@@ -176,28 +176,7 @@ func SearchRepository(opts *SearchRepoOptions) (RepositoryList, int64, error) {
if opts.Private {
if !opts.UserIsAdmin && opts.UserID != 0 && opts.UserID != opts.OwnerID {
// OK we're in the context of a User
- // We should be Either
- cond = cond.And(builder.Or(
- // 1. Be able to see all non-private repositories that either:
- cond.And(
- builder.Eq{"is_private": false},
- builder.Or(
- // A. Aren't in organisations __OR__
- builder.NotIn("owner_id", builder.Select("id").From("`user`").Where(builder.Eq{"type": UserTypeOrganization})),
- // B. Isn't a private organisation. (Limited is OK because we're logged in)
- builder.NotIn("owner_id", builder.Select("id").From("`user`").Where(builder.Eq{"visibility": structs.VisibleTypePrivate}))),
- ),
- // 2. Be able to see all repositories that we have access to
- builder.In("id", builder.Select("repo_id").
- From("`access`").
- Where(builder.And(
- builder.Eq{"user_id": opts.UserID},
- builder.Gt{"mode": int(AccessModeNone)}))),
- // 3. Be able to see all repositories that we are in a team
- builder.In("id", builder.Select("`team_repo`.repo_id").
- From("team_repo").
- Where(builder.Eq{"`team_user`.uid": opts.UserID}).
- Join("INNER", "team_user", "`team_user`.team_id = `team_repo`.team_id"))))
+ cond = cond.And(accessibleRepositoryCondition(opts.UserID))
}
} else {
// Not looking at private organisations
@@ -316,6 +295,31 @@ func SearchRepository(opts *SearchRepoOptions) (RepositoryList, int64, error) {
return repos, count, nil
}
+// accessibleRepositoryCondition takes a user a returns a condition for checking if a repository is accessible
+func accessibleRepositoryCondition(userID int64) builder.Cond {
+ return builder.Or(
+ // 1. Be able to see all non-private repositories that either:
+ builder.And(
+ builder.Eq{"`repository`.is_private": false},
+ builder.Or(
+ // A. Aren't in organisations __OR__
+ builder.NotIn("`repository`.owner_id", builder.Select("id").From("`user`").Where(builder.Eq{"type": UserTypeOrganization})),
+ // B. Isn't a private organisation. (Limited is OK because we're logged in)
+ builder.NotIn("`repository`.owner_id", builder.Select("id").From("`user`").Where(builder.Eq{"visibility": structs.VisibleTypePrivate}))),
+ ),
+ // 2. Be able to see all repositories that we have access to
+ builder.In("`repository`.id", builder.Select("repo_id").
+ From("`access`").
+ Where(builder.And(
+ builder.Eq{"user_id": userID},
+ builder.Gt{"mode": int(AccessModeNone)}))),
+ // 3. Be able to see all repositories that we are in a team
+ builder.In("`repository`.id", builder.Select("`team_repo`.repo_id").
+ From("team_repo").
+ Where(builder.Eq{"`team_user`.uid": userID}).
+ Join("INNER", "team_user", "`team_user`.team_id = `team_repo`.team_id")))
+}
+
// SearchRepositoryByName takes keyword and part of repository name to search,
// it returns results in given range and number of total results.
func SearchRepositoryByName(opts *SearchRepoOptions) (RepositoryList, int64, error) {