diff options
Diffstat (limited to 'models/migrations/migrations.go')
-rw-r--r-- | models/migrations/migrations.go | 109 |
1 files changed, 108 insertions, 1 deletions
diff --git a/models/migrations/migrations.go b/models/migrations/migrations.go index 3586e5d0b6..f0ed10b7aa 100644 --- a/models/migrations/migrations.go +++ b/models/migrations/migrations.go @@ -2,6 +2,9 @@ package migrations import ( "errors" + "strconv" + "strings" + "time" "github.com/go-xorm/xorm" ) @@ -16,7 +19,9 @@ type Version struct { // This is a sequence of migrations. Add new migrations to the bottom of the list. // If you want to "retire" a migration, replace it with "expiredMigration" -var migrations = []migration{} +var migrations = []migration{ + accessToCollaboration, +} // Migrate database to current version func Migrate(x *xorm.Engine) error { @@ -29,6 +34,21 @@ func Migrate(x *xorm.Engine) error { if err != nil { return err } else if !has { + needsMigration, err := x.IsTableExist("user") + if err != nil { + return err + } + if needsMigration { + isEmpty, err := x.IsTableEmpty("user") + if err != nil { + return err + } + needsMigration = !isEmpty + } + if !needsMigration { + currentVersion.Version = int64(len(migrations)) + } + if _, err = x.InsertOne(currentVersion); err != nil { return err } @@ -51,3 +71,90 @@ func Migrate(x *xorm.Engine) error { func expiredMigration(x *xorm.Engine) error { return errors.New("You are migrating from a too old gogs version") } + +func mustParseInt64(in []byte) int64 { + i, err := strconv.ParseInt(string(in), 10, 64) + if err != nil { + i = 0 + } + return i +} + +func accessToCollaboration(x *xorm.Engine) error { + type Collaboration struct { + ID int64 `xorm:"pk autoincr"` + RepoID int64 `xorm:"UNIQUE(s) INDEX NOT NULL"` + UserID int64 `xorm:"UNIQUE(s) INDEX NOT NULL"` + Created time.Time `xorm:"CREATED"` + } + + x.Sync(new(Collaboration)) + + sql := `SELECT u.id AS uid, a.repo_name AS repo, a.mode AS mode, a.created as created FROM access a JOIN user u ON a.user_name=u.lower_name` + results, err := x.Query(sql) + if err != nil { + return err + } + + for _, result := range results { + userID := mustParseInt64(result["uid"]) + repoRefName := string(result["repo"]) + mode := mustParseInt64(result["mode"]) + created := result["created"] + + //Collaborators must have write access + if mode < 2 { + continue + } + + // find owner of repository + parts := strings.SplitN(repoRefName, "/", 2) + ownerName := parts[0] + repoName := parts[1] + + sql = `SELECT u.id as uid, ou.uid as memberid FROM user u LEFT JOIN org_user ou ON ou.org_id=u.id WHERE u.lower_name=?` + results, err := x.Query(sql, ownerName) + if err != nil { + return err + } + if len(results) < 1 { + continue + } + + ownerID := mustParseInt64(results[0]["uid"]) + if ownerID == userID { + continue + } + + // test if user is member of owning organization + isMember := false + for _, member := range results { + memberID := mustParseInt64(member["memberid"]) + // We can skip all cases that a user is member of the owning organization + if memberID == userID { + isMember = true + } + } + if isMember { + continue + } + + sql = `SELECT id FROM repository WHERE owner_id=? AND lower_name=?` + results, err = x.Query(sql, ownerID, repoName) + if err != nil { + return err + } + if len(results) < 1 { + continue + } + + repoID := results[0]["id"] + + sql = `INSERT INTO collaboration (user_id, repo_id, created) VALUES (?,?,?)` + _, err = x.Exec(sql, userID, repoID, created) + if err != nil { + return err + } + } + return nil +} |