From b3000ae623c30a58d3eb25c9fd7104db274381b7 Mon Sep 17 00:00:00 2001
From: Lunny Xiao <xiaolunwen@gmail.com>
Date: Sun, 11 Nov 2018 03:45:32 +0800
Subject: [PATCH] Fix create team, update team missing units (#5188)

---
 Gopkg.lock                                 |  4 +-
 models/org_team.go                         | 26 ++++++++++++
 models/unit.go                             | 17 ++++++++
 routers/api/v1/convert/convert.go          |  1 +
 routers/api/v1/org/team.go                 | 27 ++++++++++++
 templates/swagger/v1_json.tmpl             | 48 ++++++++++++++++++++++
 vendor/code.gitea.io/sdk/gitea/org_team.go |  7 ++++
 7 files changed, 128 insertions(+), 2 deletions(-)

diff --git a/Gopkg.lock b/Gopkg.lock
index 2da402ba74..1a2b4b5f5b 100644
--- a/Gopkg.lock
+++ b/Gopkg.lock
@@ -11,11 +11,11 @@
 
 [[projects]]
   branch = "master"
-  digest = "1:bf4f822f636b99ac7d4f8fa5210a7439bacaf8d1f15d5783956bdd5dd2069bdc"
+  digest = "1:b194da40b41ae99546dfeec5a85f1fec2a6c51350d438e511ef90f4293c6dcd7"
   name = "code.gitea.io/sdk"
   packages = ["gitea"]
   pruneopts = "NUT"
-  revision = "11c860c8e49a23be26e6d6c6a039a46ad2ae1d27"
+  revision = "4f96d9ac89886e78c50de8c835ebe87461578a5e"
 
 [[projects]]
   digest = "1:3fcef06a1a6561955c94af6c7757a6fa37605eb653f0d06ab960e5bb80092195"
diff --git a/models/org_team.go b/models/org_team.go
index ad11431a49..53c1ec34d8 100644
--- a/models/org_team.go
+++ b/models/org_team.go
@@ -40,6 +40,14 @@ func (t *Team) getUnits(e Engine) (err error) {
 	return err
 }
 
+// GetUnitNames returns the team units names
+func (t *Team) GetUnitNames() (res []string) {
+	for _, u := range t.Units {
+		res = append(res, Units[u.Type].NameKey)
+	}
+	return
+}
+
 // HasWriteAccess returns true if team has at least write level access mode.
 func (t *Team) HasWriteAccess() bool {
 	return t.Authorize >= AccessModeWrite
@@ -367,6 +375,24 @@ func UpdateTeam(t *Team, authChanged bool) (err error) {
 		return fmt.Errorf("update: %v", err)
 	}
 
+	// update units for team
+	if len(t.Units) > 0 {
+		for _, unit := range t.Units {
+			unit.TeamID = t.ID
+		}
+		// Delete team-unit.
+		if _, err := sess.
+			Where("team_id=?", t.ID).
+			Delete(new(TeamUnit)); err != nil {
+			return err
+		}
+
+		if _, err = sess.Insert(&t.Units); err != nil {
+			sess.Rollback()
+			return err
+		}
+	}
+
 	// Update access for team members if needed.
 	if authChanged {
 		if err = t.getRepositories(sess); err != nil {
diff --git a/models/unit.go b/models/unit.go
index 1d26359528..9619232cf4 100644
--- a/models/unit.go
+++ b/models/unit.go
@@ -4,6 +4,10 @@
 
 package models
 
+import (
+	"strings"
+)
+
 // UnitType is Unit's Type
 type UnitType int
 
@@ -137,3 +141,16 @@ var (
 		UnitTypeExternalWiki:    UnitExternalWiki,
 	}
 )
+
+// FindUnitTypes give the unit key name and return unit
+func FindUnitTypes(nameKeys ...string) (res []UnitType) {
+	for _, key := range nameKeys {
+		for t, u := range Units {
+			if strings.EqualFold(key, u.NameKey) {
+				res = append(res, t)
+				break
+			}
+		}
+	}
+	return
+}
diff --git a/routers/api/v1/convert/convert.go b/routers/api/v1/convert/convert.go
index 1bfeae34bf..35416dea51 100644
--- a/routers/api/v1/convert/convert.go
+++ b/routers/api/v1/convert/convert.go
@@ -198,5 +198,6 @@ func ToTeam(team *models.Team) *api.Team {
 		Name:        team.Name,
 		Description: team.Description,
 		Permission:  team.Authorize.String(),
+		Units:       team.GetUnitNames(),
 	}
 }
diff --git a/routers/api/v1/org/team.go b/routers/api/v1/org/team.go
index 2e319a1831..8b67eda42f 100644
--- a/routers/api/v1/org/team.go
+++ b/routers/api/v1/org/team.go
@@ -90,6 +90,20 @@ func CreateTeam(ctx *context.APIContext, form api.CreateTeamOption) {
 		Description: form.Description,
 		Authorize:   models.ParseAccessMode(form.Permission),
 	}
+
+	unitTypes := models.FindUnitTypes(form.Units...)
+
+	if team.Authorize < models.AccessModeOwner {
+		var units = make([]*models.TeamUnit, 0, len(form.Units))
+		for _, tp := range unitTypes {
+			units = append(units, &models.TeamUnit{
+				OrgID: ctx.Org.Organization.ID,
+				Type:  tp,
+			})
+		}
+		team.Units = units
+	}
+
 	if err := models.NewTeam(team); err != nil {
 		if models.IsErrTeamAlreadyExist(err) {
 			ctx.Error(422, "", err)
@@ -128,6 +142,19 @@ func EditTeam(ctx *context.APIContext, form api.EditTeamOption) {
 	team.Name = form.Name
 	team.Description = form.Description
 	team.Authorize = models.ParseAccessMode(form.Permission)
+	unitTypes := models.FindUnitTypes(form.Units...)
+
+	if team.Authorize < models.AccessModeOwner {
+		var units = make([]*models.TeamUnit, 0, len(form.Units))
+		for _, tp := range unitTypes {
+			units = append(units, &models.TeamUnit{
+				OrgID: ctx.Org.Organization.ID,
+				Type:  tp,
+			})
+		}
+		team.Units = units
+	}
+
 	if err := models.UpdateTeam(team, true); err != nil {
 		ctx.Error(500, "EditTeam", err)
 		return
diff --git a/templates/swagger/v1_json.tmpl b/templates/swagger/v1_json.tmpl
index 56a169c295..5c8c666041 100644
--- a/templates/swagger/v1_json.tmpl
+++ b/templates/swagger/v1_json.tmpl
@@ -6322,6 +6322,22 @@
             "admin"
           ],
           "x-go-name": "Permission"
+        },
+        "units": {
+          "type": "array",
+          "enum": [
+            "repo.code",
+            "repo.issues",
+            "repo.ext_issues",
+            "repo.wiki",
+            "repo.pulls",
+            "repo.releases",
+            "repo.ext_wiki"
+          ],
+          "items": {
+            "type": "string"
+          },
+          "x-go-name": "Units"
         }
       },
       "x-go-package": "code.gitea.io/gitea/vendor/code.gitea.io/sdk/gitea"
@@ -6697,6 +6713,22 @@
             "admin"
           ],
           "x-go-name": "Permission"
+        },
+        "units": {
+          "type": "array",
+          "enum": [
+            "repo.code",
+            "repo.issues",
+            "repo.ext_issues",
+            "repo.wiki",
+            "repo.pulls",
+            "repo.releases",
+            "repo.ext_wiki"
+          ],
+          "items": {
+            "type": "string"
+          },
+          "x-go-name": "Units"
         }
       },
       "x-go-package": "code.gitea.io/gitea/vendor/code.gitea.io/sdk/gitea"
@@ -7744,6 +7776,22 @@
             "owner"
           ],
           "x-go-name": "Permission"
+        },
+        "units": {
+          "type": "array",
+          "enum": [
+            "repo.code",
+            "repo.issues",
+            "repo.ext_issues",
+            "repo.wiki",
+            "repo.pulls",
+            "repo.releases",
+            "repo.ext_wiki"
+          ],
+          "items": {
+            "type": "string"
+          },
+          "x-go-name": "Units"
         }
       },
       "x-go-package": "code.gitea.io/gitea/vendor/code.gitea.io/sdk/gitea"
diff --git a/vendor/code.gitea.io/sdk/gitea/org_team.go b/vendor/code.gitea.io/sdk/gitea/org_team.go
index 2fc6796d43..f3e98b932e 100644
--- a/vendor/code.gitea.io/sdk/gitea/org_team.go
+++ b/vendor/code.gitea.io/sdk/gitea/org_team.go
@@ -1,4 +1,5 @@
 // Copyright 2016 The Gogs Authors. All rights reserved.
+// Copyright 2018 The Gitea Authors. All rights reserved.
 // Use of this source code is governed by a MIT-style
 // license that can be found in the LICENSE file.
 
@@ -11,6 +12,8 @@ type Team struct {
 	Description string `json:"description"`
 	// enum: none,read,write,admin,owner
 	Permission string `json:"permission"`
+	// enum: repo.code,repo.issues,repo.ext_issues,repo.wiki,repo.pulls,repo.releases,repo.ext_wiki
+	Units []string `json:"units"`
 }
 
 // CreateTeamOption options for creating a team
@@ -20,6 +23,8 @@ type CreateTeamOption struct {
 	Description string `json:"description" binding:"MaxSize(255)"`
 	// enum: read,write,admin
 	Permission string `json:"permission"`
+	// enum: repo.code,repo.issues,repo.ext_issues,repo.wiki,repo.pulls,repo.releases,repo.ext_wiki
+	Units []string `json:"units"`
 }
 
 // EditTeamOption options for editing a team
@@ -29,4 +34,6 @@ type EditTeamOption struct {
 	Description string `json:"description" binding:"MaxSize(255)"`
 	// enum: read,write,admin
 	Permission string `json:"permission"`
+	// enum: repo.code,repo.issues,repo.ext_issues,repo.wiki,repo.pulls,repo.releases,repo.ext_wiki
+	Units []string `json:"units"`
 }