summaryrefslogtreecommitdiffstats
path: root/models/migrations/migrations.go
diff options
context:
space:
mode:
Diffstat (limited to 'models/migrations/migrations.go')
-rw-r--r--models/migrations/migrations.go109
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
+}