mirror of
				https://github.com/go-gitea/gitea.git
				synced 2025-11-04 01:34:27 +00:00 
			
		
		
		
	Finish new edit team page, add member to team
This commit is contained in:
		@@ -48,7 +48,7 @@ and it takes care of all the other things for you`,
 | 
				
			|||||||
	Flags:  []cli.Flag{},
 | 
						Flags:  []cli.Flag{},
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// checkVersion checks if binary matches the version of temolate files.
 | 
					// checkVersion checks if binary matches the version of templates files.
 | 
				
			||||||
func checkVersion() {
 | 
					func checkVersion() {
 | 
				
			||||||
	data, err := ioutil.ReadFile(path.Join(setting.StaticRootPath, "templates/.VERSION"))
 | 
						data, err := ioutil.ReadFile(path.Join(setting.StaticRootPath, "templates/.VERSION"))
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
@@ -235,7 +235,7 @@ func runWeb(*cli.Context) {
 | 
				
			|||||||
			r.Get("/members/action/:action", org.MembersAction)
 | 
								r.Get("/members/action/:action", org.MembersAction)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			r.Get("/teams", org.Teams)
 | 
								r.Get("/teams", org.Teams)
 | 
				
			||||||
			r.Get("/teams/:team", org.SingleTeam)
 | 
								r.Get("/teams/:team", org.TeamMembers)
 | 
				
			||||||
			r.Get("/teams/:team/action/:action", org.TeamsAction)
 | 
								r.Get("/teams/:team/action/:action", org.TeamsAction)
 | 
				
			||||||
		}, middleware.OrgAssignment(true, true))
 | 
							}, middleware.OrgAssignment(true, true))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -243,6 +243,8 @@ func runWeb(*cli.Context) {
 | 
				
			|||||||
			r.Get("/teams/new", org.NewTeam)
 | 
								r.Get("/teams/new", org.NewTeam)
 | 
				
			||||||
			r.Post("/teams/new", bindIgnErr(auth.CreateTeamForm{}), org.NewTeamPost)
 | 
								r.Post("/teams/new", bindIgnErr(auth.CreateTeamForm{}), org.NewTeamPost)
 | 
				
			||||||
			r.Get("/teams/:team/edit", org.EditTeam)
 | 
								r.Get("/teams/:team/edit", org.EditTeam)
 | 
				
			||||||
 | 
								r.Post("/teams/:team/edit", bindIgnErr(auth.CreateTeamForm{}), org.EditTeamPost)
 | 
				
			||||||
 | 
								r.Post("/teams/:team/delete", org.DeleteTeam)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			m.Group("/settings", func(r *macaron.Router) {
 | 
								m.Group("/settings", func(r *macaron.Router) {
 | 
				
			||||||
				r.Get("", org.Settings)
 | 
									r.Get("", org.Settings)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -283,6 +283,13 @@ teams.no_desc = This team has no description
 | 
				
			|||||||
teams.settings = Settings
 | 
					teams.settings = Settings
 | 
				
			||||||
teams.owners_permission_desc = Owners have full access to <strong>all repositories</strong> and have <strong>admin rights</strong> to the organization.
 | 
					teams.owners_permission_desc = Owners have full access to <strong>all repositories</strong> and have <strong>admin rights</strong> to the organization.
 | 
				
			||||||
teams.members = Team Members
 | 
					teams.members = Team Members
 | 
				
			||||||
 | 
					teams.update_settings = Update Settings
 | 
				
			||||||
 | 
					teams.delete_team = Delete This Team
 | 
				
			||||||
 | 
					teams.add_team_member = Add Team Member
 | 
				
			||||||
 | 
					teams.delete_team_success = Given team has been successfully deleted.
 | 
				
			||||||
 | 
					teams.read_permission_desc = This team grants <strong>Read</strong> access: members can view and clone the team's repositories.
 | 
				
			||||||
 | 
					teams.write_permission_desc = This team grants <strong>Write</strong> access: members can read from and push to the team's repositories.
 | 
				
			||||||
 | 
					teams.admin_permission_desc = This team grants <strong>Admin</strong> access: members can read from, push to, and add collaborators to the team's repositories.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[action]
 | 
					[action]
 | 
				
			||||||
create_repo = created repository <a href="/%s">%s</a>
 | 
					create_repo = created repository <a href="/%s">%s</a>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -283,6 +283,13 @@ teams.no_desc = 该团队暂无描述
 | 
				
			|||||||
teams.settings = 团队设置
 | 
					teams.settings = 团队设置
 | 
				
			||||||
teams.owners_permission_desc = 管理员团队对 <strong>所有仓库</strong> 具有操作权限,且对组织具有 <strong>管理员权限</strong>。
 | 
					teams.owners_permission_desc = 管理员团队对 <strong>所有仓库</strong> 具有操作权限,且对组织具有 <strong>管理员权限</strong>。
 | 
				
			||||||
teams.members = 团队成员
 | 
					teams.members = 团队成员
 | 
				
			||||||
 | 
					teams.update_settings = 更新团队设置
 | 
				
			||||||
 | 
					teams.delete_team = 删除当前团队
 | 
				
			||||||
 | 
					teams.add_team_member = 添加团队成员
 | 
				
			||||||
 | 
					teams.delete_team_success = 指定团队已经被成功删除!
 | 
				
			||||||
 | 
					teams.read_permission_desc = 该团队拥有对所属仓库的 <strong>读取</strong> 权限,团队成员可以进行查看和克隆等只读操作。
 | 
				
			||||||
 | 
					teams.write_permission_desc = 该团队拥有对所属仓库的 <strong>读取</strong> 和 <strong>写入</strong> 的权限。
 | 
				
			||||||
 | 
					teams.admin_permission_desc = 该团队拥有一定的 <strong>管理</strong> 权限,团队成员可以读取、克隆、推送以及添加其它仓库协作者。
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[action]
 | 
					[action]
 | 
				
			||||||
create_repo = 创建了仓库 <a href="/%s">%s</a>
 | 
					create_repo = 创建了仓库 <a href="/%s">%s</a>
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										2
									
								
								gogs.go
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								gogs.go
									
									
									
									
									
								
							@@ -17,7 +17,7 @@ import (
 | 
				
			|||||||
	"github.com/gogits/gogs/modules/setting"
 | 
						"github.com/gogits/gogs/modules/setting"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const APP_VER = "0.4.7.0823 Alpha"
 | 
					const APP_VER = "0.4.7.0824 Alpha"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func init() {
 | 
					func init() {
 | 
				
			||||||
	runtime.GOMAXPROCS(runtime.NumCPU())
 | 
						runtime.GOMAXPROCS(runtime.NumCPU())
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										376
									
								
								models/org.go
									
									
									
									
									
								
							
							
						
						
									
										376
									
								
								models/org.go
									
									
									
									
									
								
							@@ -6,11 +6,13 @@ package models
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
	"errors"
 | 
						"errors"
 | 
				
			||||||
 | 
						"fmt"
 | 
				
			||||||
	"os"
 | 
						"os"
 | 
				
			||||||
	"path"
 | 
						"path"
 | 
				
			||||||
	"strings"
 | 
						"strings"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"github.com/Unknwon/com"
 | 
						"github.com/Unknwon/com"
 | 
				
			||||||
 | 
						"github.com/go-xorm/xorm"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"github.com/gogits/gogs/modules/base"
 | 
						"github.com/gogits/gogs/modules/base"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
@@ -134,10 +136,10 @@ func CreateOrganization(org, owner *User) (*User, error) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	// Add initial creator to organization and owner team.
 | 
						// Add initial creator to organization and owner team.
 | 
				
			||||||
	ou := &OrgUser{
 | 
						ou := &OrgUser{
 | 
				
			||||||
		Uid:     owner.Id,
 | 
							Uid:      owner.Id,
 | 
				
			||||||
		OrgId:   org.Id,
 | 
							OrgId:    org.Id,
 | 
				
			||||||
		IsOwner: true,
 | 
							IsOwner:  true,
 | 
				
			||||||
		NumTeam: 1,
 | 
							NumTeams: 1,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if _, err = sess.Insert(ou); err != nil {
 | 
						if _, err = sess.Insert(ou); err != nil {
 | 
				
			||||||
		sess.Rollback()
 | 
							sess.Rollback()
 | 
				
			||||||
@@ -199,7 +201,7 @@ type OrgUser struct {
 | 
				
			|||||||
	OrgId    int64 `xorm:"INDEX UNIQUE(s)"`
 | 
						OrgId    int64 `xorm:"INDEX UNIQUE(s)"`
 | 
				
			||||||
	IsPublic bool
 | 
						IsPublic bool
 | 
				
			||||||
	IsOwner  bool
 | 
						IsOwner  bool
 | 
				
			||||||
	NumTeam  int
 | 
						NumTeams int
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// IsOrganizationOwner returns true if given user is in the owner team.
 | 
					// IsOrganizationOwner returns true if given user is in the owner team.
 | 
				
			||||||
@@ -255,17 +257,17 @@ func AddOrgUser(orgId, uid int64) error {
 | 
				
			|||||||
		return nil
 | 
							return nil
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ou := &OrgUser{
 | 
					 | 
				
			||||||
		Uid:   uid,
 | 
					 | 
				
			||||||
		OrgId: orgId,
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	sess := x.NewSession()
 | 
						sess := x.NewSession()
 | 
				
			||||||
	defer sess.Close()
 | 
						defer sess.Close()
 | 
				
			||||||
	if err := sess.Begin(); err != nil {
 | 
						if err := sess.Begin(); err != nil {
 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ou := &OrgUser{
 | 
				
			||||||
 | 
							Uid:   uid,
 | 
				
			||||||
 | 
							OrgId: orgId,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if _, err := sess.Insert(ou); err != nil {
 | 
						if _, err := sess.Insert(ou); err != nil {
 | 
				
			||||||
		sess.Rollback()
 | 
							sess.Rollback()
 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
@@ -288,12 +290,17 @@ func RemoveOrgUser(orgId, uid int64) error {
 | 
				
			|||||||
		return nil
 | 
							return nil
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						u, err := GetUserById(uid)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						org, err := GetUserById(orgId)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Check if the user to delete is the last member in owner team.
 | 
						// Check if the user to delete is the last member in owner team.
 | 
				
			||||||
	if IsOrganizationOwner(orgId, uid) {
 | 
						if IsOrganizationOwner(orgId, uid) {
 | 
				
			||||||
		org, err := GetUserById(orgId)
 | 
					 | 
				
			||||||
		if err != nil {
 | 
					 | 
				
			||||||
			return err
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		t, err := org.GetOwnerTeam()
 | 
							t, err := org.GetOwnerTeam()
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
			return err
 | 
								return err
 | 
				
			||||||
@@ -317,6 +324,33 @@ func RemoveOrgUser(orgId, uid int64) error {
 | 
				
			|||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Delete all repository accesses.
 | 
				
			||||||
 | 
						if err = org.GetRepositories(); err != nil {
 | 
				
			||||||
 | 
							sess.Rollback()
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						access := &Access{
 | 
				
			||||||
 | 
							UserName: u.LowerName,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						for _, repo := range org.Repos {
 | 
				
			||||||
 | 
							access.RepoName = path.Join(org.LowerName, repo.LowerName)
 | 
				
			||||||
 | 
							if _, err = sess.Delete(access); err != nil {
 | 
				
			||||||
 | 
								sess.Rollback()
 | 
				
			||||||
 | 
								return err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Delete member in his/her teams.
 | 
				
			||||||
 | 
						ts, err := GetUserTeams(org.Id, u.Id)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						for _, t := range ts {
 | 
				
			||||||
 | 
							if err = removeTeamMemberWithSess(org.Id, t.Id, u.Id, sess); err != nil {
 | 
				
			||||||
 | 
								return err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return sess.Commit()
 | 
						return sess.Commit()
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -352,6 +386,11 @@ type Team struct {
 | 
				
			|||||||
	NumMembers  int
 | 
						NumMembers  int
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// IsOwnerTeam returns true if team is owner team.
 | 
				
			||||||
 | 
					func (t *Team) IsOwnerTeam() bool {
 | 
				
			||||||
 | 
						return t.Name == OWNER_TEAM
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// IsTeamMember returns true if given user is a member of team.
 | 
					// IsTeamMember returns true if given user is a member of team.
 | 
				
			||||||
func (t *Team) IsMember(uid int64) bool {
 | 
					func (t *Team) IsMember(uid int64) bool {
 | 
				
			||||||
	return IsTeamMember(t.OrgId, t.Id, uid)
 | 
						return IsTeamMember(t.OrgId, t.Id, uid)
 | 
				
			||||||
@@ -362,7 +401,10 @@ func (t *Team) GetRepositories() error {
 | 
				
			|||||||
	idStrs := strings.Split(t.RepoIds, "|")
 | 
						idStrs := strings.Split(t.RepoIds, "|")
 | 
				
			||||||
	t.Repos = make([]*Repository, 0, len(idStrs))
 | 
						t.Repos = make([]*Repository, 0, len(idStrs))
 | 
				
			||||||
	for _, str := range idStrs {
 | 
						for _, str := range idStrs {
 | 
				
			||||||
		id := com.StrTo(str).MustInt64()
 | 
							if len(str) == 0 {
 | 
				
			||||||
 | 
								continue
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							id := com.StrTo(str[1:]).MustInt64()
 | 
				
			||||||
		if id == 0 {
 | 
							if id == 0 {
 | 
				
			||||||
			continue
 | 
								continue
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
@@ -459,15 +501,177 @@ func GetTeamById(teamId int64) (*Team, error) {
 | 
				
			|||||||
	return t, nil
 | 
						return t, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// GetHighestAuthorize returns highest repository authorize level for given user and team.
 | 
				
			||||||
 | 
					func GetHighestAuthorize(orgId, uid, teamId, repoId int64) (AuthorizeType, error) {
 | 
				
			||||||
 | 
						ts, err := GetUserTeams(orgId, uid)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return 0, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						var auth AuthorizeType = 0
 | 
				
			||||||
 | 
						for _, t := range ts {
 | 
				
			||||||
 | 
							// Not current team and has given repository.
 | 
				
			||||||
 | 
							if t.Id != teamId && strings.Contains(t.RepoIds, "$"+com.ToStr(repoId)+"|") {
 | 
				
			||||||
 | 
								// Fast return.
 | 
				
			||||||
 | 
								if t.Authorize == ORG_WRITABLE {
 | 
				
			||||||
 | 
									return ORG_WRITABLE, nil
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								if t.Authorize > auth {
 | 
				
			||||||
 | 
									auth = t.Authorize
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return auth, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// UpdateTeam updates information of team.
 | 
					// UpdateTeam updates information of team.
 | 
				
			||||||
func UpdateTeam(t *Team) error {
 | 
					func UpdateTeam(t *Team, authChanged bool) (err error) {
 | 
				
			||||||
 | 
						if !IsLegalName(t.Name) {
 | 
				
			||||||
 | 
							return ErrTeamNameIllegal
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if len(t.Description) > 255 {
 | 
						if len(t.Description) > 255 {
 | 
				
			||||||
		t.Description = t.Description[:255]
 | 
							t.Description = t.Description[:255]
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						sess := x.NewSession()
 | 
				
			||||||
 | 
						defer sess.Close()
 | 
				
			||||||
 | 
						if err = sess.Begin(); err != nil {
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Update access for team members if needed.
 | 
				
			||||||
 | 
						if authChanged && !t.IsOwnerTeam() {
 | 
				
			||||||
 | 
							if err = t.GetRepositories(); err != nil {
 | 
				
			||||||
 | 
								return err
 | 
				
			||||||
 | 
							} else if err = t.GetMembers(); err != nil {
 | 
				
			||||||
 | 
								return err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// Get organization.
 | 
				
			||||||
 | 
							org, err := GetUserById(t.OrgId)
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								return err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							mode := READABLE
 | 
				
			||||||
 | 
							if t.Authorize > ORG_READABLE {
 | 
				
			||||||
 | 
								mode = WRITABLE
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							access := &Access{
 | 
				
			||||||
 | 
								Mode: mode,
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							for _, repo := range t.Repos {
 | 
				
			||||||
 | 
								access.RepoName = path.Join(org.LowerName, repo.LowerName)
 | 
				
			||||||
 | 
								for _, u := range t.Members {
 | 
				
			||||||
 | 
									// ORG_WRITABLE is the highest authorize level for now.
 | 
				
			||||||
 | 
									// Skip checking others if current team has this level.
 | 
				
			||||||
 | 
									if t.Authorize < ORG_WRITABLE {
 | 
				
			||||||
 | 
										auth, err := GetHighestAuthorize(org.Id, u.Id, t.Id, repo.Id)
 | 
				
			||||||
 | 
										if err != nil {
 | 
				
			||||||
 | 
											sess.Rollback()
 | 
				
			||||||
 | 
											return err
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
										if auth >= t.Authorize {
 | 
				
			||||||
 | 
											continue // Other team has higher or same authorize level.
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									access.UserName = u.LowerName
 | 
				
			||||||
 | 
									if _, err = sess.Update(access); err != nil {
 | 
				
			||||||
 | 
										sess.Rollback()
 | 
				
			||||||
 | 
										return err
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	t.LowerName = strings.ToLower(t.Name)
 | 
						t.LowerName = strings.ToLower(t.Name)
 | 
				
			||||||
	_, err := x.Id(t.Id).AllCols().Update(t)
 | 
						if _, err = sess.Id(t.Id).AllCols().Update(t); err != nil {
 | 
				
			||||||
	return err
 | 
							sess.Rollback()
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return sess.Commit()
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// DeleteTeam deletes given team.
 | 
				
			||||||
 | 
					// It's caller's responsibility to assign organization ID.
 | 
				
			||||||
 | 
					func DeleteTeam(t *Team) error {
 | 
				
			||||||
 | 
						if err := t.GetRepositories(); err != nil {
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						} else if err = t.GetMembers(); err != nil {
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Get organization.
 | 
				
			||||||
 | 
						org, err := GetUserById(t.OrgId)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						sess := x.NewSession()
 | 
				
			||||||
 | 
						defer sess.Close()
 | 
				
			||||||
 | 
						if err = sess.Begin(); err != nil {
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Delete all accesses.
 | 
				
			||||||
 | 
						mode := READABLE
 | 
				
			||||||
 | 
						if t.Authorize > ORG_READABLE {
 | 
				
			||||||
 | 
							mode = WRITABLE
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						access := new(Access)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for _, repo := range t.Repos {
 | 
				
			||||||
 | 
							access.RepoName = path.Join(org.LowerName, repo.LowerName)
 | 
				
			||||||
 | 
							for _, u := range t.Members {
 | 
				
			||||||
 | 
								access.UserName = u.LowerName
 | 
				
			||||||
 | 
								access.Mode = mode
 | 
				
			||||||
 | 
								auth, err := GetHighestAuthorize(org.Id, u.Id, t.Id, repo.Id)
 | 
				
			||||||
 | 
								if err != nil {
 | 
				
			||||||
 | 
									sess.Rollback()
 | 
				
			||||||
 | 
									return err
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								if auth == 0 {
 | 
				
			||||||
 | 
									if _, err = sess.Delete(access); err != nil {
 | 
				
			||||||
 | 
										sess.Rollback()
 | 
				
			||||||
 | 
										return err
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								} else if auth < t.Authorize {
 | 
				
			||||||
 | 
									// Downgrade authorize level.
 | 
				
			||||||
 | 
									mode := READABLE
 | 
				
			||||||
 | 
									if auth > ORG_READABLE {
 | 
				
			||||||
 | 
										mode = WRITABLE
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									access.Mode = mode
 | 
				
			||||||
 | 
									if _, err = sess.Update(access); err != nil {
 | 
				
			||||||
 | 
										sess.Rollback()
 | 
				
			||||||
 | 
										return err
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Delete team-user.
 | 
				
			||||||
 | 
						if _, err = sess.Where("org_id=?", org.Id).Where("team_id=?", t.Id).Delete(new(TeamUser)); err != nil {
 | 
				
			||||||
 | 
							sess.Rollback()
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Delete team.
 | 
				
			||||||
 | 
						if _, err = sess.Id(t.Id).Delete(new(Team)); err != nil {
 | 
				
			||||||
 | 
							sess.Rollback()
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						// Update organization number of teams.
 | 
				
			||||||
 | 
						if _, err = sess.Exec("UPDATE `user` SET num_teams = num_teams - 1 WHERE id = ?", t.OrgId); err != nil {
 | 
				
			||||||
 | 
							sess.Rollback()
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return sess.Commit()
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// ___________                    ____ ___
 | 
					// ___________                    ____ ___
 | 
				
			||||||
@@ -509,12 +713,37 @@ func GetTeamMembers(orgId, teamId int64) ([]*User, error) {
 | 
				
			|||||||
	return us, nil
 | 
						return us, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// GetUserTeams returns all teams that user belongs to in given origanization.
 | 
				
			||||||
 | 
					func GetUserTeams(orgId, uid int64) ([]*Team, error) {
 | 
				
			||||||
 | 
						tus := make([]*TeamUser, 0, 5)
 | 
				
			||||||
 | 
						if err := x.Where("uid=?", uid).And("org_id=?", orgId).Find(&tus); err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ts := make([]*Team, len(tus))
 | 
				
			||||||
 | 
						for i, tu := range tus {
 | 
				
			||||||
 | 
							t := new(Team)
 | 
				
			||||||
 | 
							has, err := x.Id(tu.TeamId).Get(t)
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								return nil, err
 | 
				
			||||||
 | 
							} else if !has {
 | 
				
			||||||
 | 
								return nil, ErrTeamNotExist
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							ts[i] = t
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return ts, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// AddTeamMember adds new member to given team of given organization.
 | 
					// AddTeamMember adds new member to given team of given organization.
 | 
				
			||||||
func AddTeamMember(orgId, teamId, uid int64) error {
 | 
					func AddTeamMember(orgId, teamId, uid int64) error {
 | 
				
			||||||
	if !IsOrganizationMember(orgId, uid) || IsTeamMember(orgId, teamId, uid) {
 | 
						if IsTeamMember(orgId, teamId, uid) {
 | 
				
			||||||
		return nil
 | 
							return nil
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if err := AddOrgUser(orgId, uid); err != nil {
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Get team and its repositories.
 | 
						// Get team and its repositories.
 | 
				
			||||||
	t, err := GetTeamById(teamId)
 | 
						t, err := GetTeamById(teamId)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
@@ -569,18 +798,49 @@ func AddTeamMember(orgId, teamId, uid int64) error {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	// Give access to team repositories.
 | 
						// Give access to team repositories.
 | 
				
			||||||
	for _, repo := range t.Repos {
 | 
						for _, repo := range t.Repos {
 | 
				
			||||||
		access.RepoName = path.Join(org.LowerName, repo.LowerName)
 | 
							auth, err := GetHighestAuthorize(orgId, uid, teamId, repo.Id)
 | 
				
			||||||
		if _, err = sess.Insert(access); err != nil {
 | 
							if err != nil {
 | 
				
			||||||
			sess.Rollback()
 | 
								sess.Rollback()
 | 
				
			||||||
			return err
 | 
								return err
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							access.Id = 0
 | 
				
			||||||
 | 
							access.RepoName = path.Join(org.LowerName, repo.LowerName)
 | 
				
			||||||
 | 
							// Equal 0 means given access doesn't exist.
 | 
				
			||||||
 | 
							if auth == 0 {
 | 
				
			||||||
 | 
								if _, err = sess.Insert(access); err != nil {
 | 
				
			||||||
 | 
									sess.Rollback()
 | 
				
			||||||
 | 
									return err
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							} else if auth < t.Authorize {
 | 
				
			||||||
 | 
								if _, err = sess.Update(access); err != nil {
 | 
				
			||||||
 | 
									sess.Rollback()
 | 
				
			||||||
 | 
									return err
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						fmt.Println("kao")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// We make sure it exists before.
 | 
				
			||||||
 | 
						ou := new(OrgUser)
 | 
				
			||||||
 | 
						_, err = sess.Where("uid=?", uid).And("org_id=?", orgId).Get(ou)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							sess.Rollback()
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						ou.NumTeams++
 | 
				
			||||||
 | 
						if t.IsOwnerTeam() {
 | 
				
			||||||
 | 
							ou.IsOwner = true
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if _, err = sess.Id(ou.Id).AllCols().Update(ou); err != nil {
 | 
				
			||||||
 | 
							sess.Rollback()
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return sess.Commit()
 | 
						return sess.Commit()
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// RemoveTeamMember removes member from given team of given organization.
 | 
					func removeTeamMemberWithSess(orgId, teamId, uid int64, sess *xorm.Session) error {
 | 
				
			||||||
func RemoveTeamMember(orgId, teamId, uid int64) error {
 | 
					 | 
				
			||||||
	if !IsTeamMember(orgId, teamId, uid) {
 | 
						if !IsTeamMember(orgId, teamId, uid) {
 | 
				
			||||||
		return nil
 | 
							return nil
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -590,6 +850,12 @@ func RemoveTeamMember(orgId, teamId, uid int64) error {
 | 
				
			|||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Check if the user to delete is the last member in owner team.
 | 
				
			||||||
 | 
						if t.IsOwnerTeam() && t.NumMembers == 1 {
 | 
				
			||||||
 | 
							return ErrLastOrgOwner
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	t.NumMembers--
 | 
						t.NumMembers--
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if err = t.GetRepositories(); err != nil {
 | 
						if err = t.GetRepositories(); err != nil {
 | 
				
			||||||
@@ -608,22 +874,12 @@ func RemoveTeamMember(orgId, teamId, uid int64) error {
 | 
				
			|||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	sess := x.NewSession()
 | 
					 | 
				
			||||||
	defer sess.Close()
 | 
					 | 
				
			||||||
	if err := sess.Begin(); err != nil {
 | 
					 | 
				
			||||||
		return err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	tu := &TeamUser{
 | 
						tu := &TeamUser{
 | 
				
			||||||
		Uid:    uid,
 | 
							Uid:    uid,
 | 
				
			||||||
		OrgId:  orgId,
 | 
							OrgId:  orgId,
 | 
				
			||||||
		TeamId: teamId,
 | 
							TeamId: teamId,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	access := &Access{
 | 
					 | 
				
			||||||
		UserName: u.LowerName,
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if _, err := sess.Delete(tu); err != nil {
 | 
						if _, err := sess.Delete(tu); err != nil {
 | 
				
			||||||
		sess.Rollback()
 | 
							sess.Rollback()
 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
@@ -633,13 +889,63 @@ func RemoveTeamMember(orgId, teamId, uid int64) error {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Delete access to team repositories.
 | 
						// Delete access to team repositories.
 | 
				
			||||||
 | 
						access := &Access{
 | 
				
			||||||
 | 
							UserName: u.LowerName,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for _, repo := range t.Repos {
 | 
						for _, repo := range t.Repos {
 | 
				
			||||||
		access.RepoName = path.Join(org.LowerName, repo.LowerName)
 | 
							auth, err := GetHighestAuthorize(orgId, uid, teamId, repo.Id)
 | 
				
			||||||
		if _, err = sess.Delete(access); err != nil {
 | 
							if err != nil {
 | 
				
			||||||
 | 
								sess.Rollback()
 | 
				
			||||||
 | 
								return err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// Delete access if this is the last team user belongs to.
 | 
				
			||||||
 | 
							if auth == 0 {
 | 
				
			||||||
 | 
								access.RepoName = path.Join(org.LowerName, repo.LowerName)
 | 
				
			||||||
 | 
								_, err = sess.Delete(access)
 | 
				
			||||||
 | 
							} else if auth < t.Authorize {
 | 
				
			||||||
 | 
								// Downgrade authorize level.
 | 
				
			||||||
 | 
								mode := READABLE
 | 
				
			||||||
 | 
								if auth > ORG_READABLE {
 | 
				
			||||||
 | 
									mode = WRITABLE
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								access.Mode = mode
 | 
				
			||||||
 | 
								_, err = sess.Update(access)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
			sess.Rollback()
 | 
								sess.Rollback()
 | 
				
			||||||
			return err
 | 
								return err
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// This must exist.
 | 
				
			||||||
 | 
						ou := new(OrgUser)
 | 
				
			||||||
 | 
						_, err = sess.Where("uid=?", uid).And("org_id=?", org.Id).Get(ou)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							sess.Rollback()
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						ou.NumTeams--
 | 
				
			||||||
 | 
						if t.IsOwnerTeam() {
 | 
				
			||||||
 | 
							ou.IsOwner = false
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if _, err = sess.Id(ou.Id).AllCols().Update(ou); err != nil {
 | 
				
			||||||
 | 
							sess.Rollback()
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// RemoveTeamMember removes member from given team of given organization.
 | 
				
			||||||
 | 
					func RemoveTeamMember(orgId, teamId, uid int64) error {
 | 
				
			||||||
 | 
						sess := x.NewSession()
 | 
				
			||||||
 | 
						defer sess.Close()
 | 
				
			||||||
 | 
						if err := sess.Begin(); err != nil {
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if err := removeTeamMemberWithSess(orgId, teamId, uid, sess); err != nil {
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	return sess.Commit()
 | 
						return sess.Commit()
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -525,6 +525,7 @@ func CreateRepository(u *User, name, desc, lang, license string, private, mirror
 | 
				
			|||||||
			return nil, err
 | 
								return nil, err
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		for _, u := range us {
 | 
							for _, u := range us {
 | 
				
			||||||
 | 
								access.Id = 0
 | 
				
			||||||
			access.UserName = u.LowerName
 | 
								access.UserName = u.LowerName
 | 
				
			||||||
			if _, err = sess.Insert(access); err != nil {
 | 
								if _, err = sess.Insert(access); err != nil {
 | 
				
			||||||
				sess.Rollback()
 | 
									sess.Rollback()
 | 
				
			||||||
@@ -707,6 +708,10 @@ func TransferOwnership(u *User, newOwner string, repo *Repository) (err error) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
// ChangeRepositoryName changes all corresponding setting from old repository name to new one.
 | 
					// ChangeRepositoryName changes all corresponding setting from old repository name to new one.
 | 
				
			||||||
func ChangeRepositoryName(userName, oldRepoName, newRepoName string) (err error) {
 | 
					func ChangeRepositoryName(userName, oldRepoName, newRepoName string) (err error) {
 | 
				
			||||||
 | 
						if !IsLegalName(newRepoName) {
 | 
				
			||||||
 | 
							return ErrRepoNameIllegal
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Update accesses.
 | 
						// Update accesses.
 | 
				
			||||||
	accesses := make([]Access, 0, 10)
 | 
						accesses := make([]Access, 0, 10)
 | 
				
			||||||
	if err = x.Find(&accesses, &Access{RepoName: strings.ToLower(userName + "/" + oldRepoName)}); err != nil {
 | 
						if err = x.Find(&accesses, &Access{RepoName: strings.ToLower(userName + "/" + oldRepoName)}); err != nil {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -54,7 +54,8 @@ type User struct {
 | 
				
			|||||||
	LoginSource   int64 `xorm:"not null default 0"`
 | 
						LoginSource   int64 `xorm:"not null default 0"`
 | 
				
			||||||
	LoginName     string
 | 
						LoginName     string
 | 
				
			||||||
	Type          UserType
 | 
						Type          UserType
 | 
				
			||||||
	Orgs          []*User `xorm:"-"`
 | 
						Orgs          []*User       `xorm:"-"`
 | 
				
			||||||
 | 
						Repos         []*Repository `xorm:"-"`
 | 
				
			||||||
	NumFollowers  int
 | 
						NumFollowers  int
 | 
				
			||||||
	NumFollowings int
 | 
						NumFollowings int
 | 
				
			||||||
	NumStars      int
 | 
						NumStars      int
 | 
				
			||||||
@@ -143,6 +144,12 @@ func (u *User) GetOrganizationCount() (int64, error) {
 | 
				
			|||||||
	return x.Where("uid=?", u.Id).Count(new(OrgUser))
 | 
						return x.Where("uid=?", u.Id).Count(new(OrgUser))
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// GetRepositories returns all repositories that user owns, including private repositories.
 | 
				
			||||||
 | 
					func (u *User) GetRepositories() (err error) {
 | 
				
			||||||
 | 
						u.Repos, err = GetRepositories(u.Id, true)
 | 
				
			||||||
 | 
						return err
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// GetOrganizations returns all organizations that user belongs to.
 | 
					// GetOrganizations returns all organizations that user belongs to.
 | 
				
			||||||
func (u *User) GetOrganizations() error {
 | 
					func (u *User) GetOrganizations() error {
 | 
				
			||||||
	ous, err := GetOrgUsersByUserId(u.Id)
 | 
						ous, err := GetOrgUsersByUserId(u.Id)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -46,6 +46,7 @@ type Context struct {
 | 
				
			|||||||
		IsBranch    bool
 | 
							IsBranch    bool
 | 
				
			||||||
		IsTag       bool
 | 
							IsTag       bool
 | 
				
			||||||
		IsCommit    bool
 | 
							IsCommit    bool
 | 
				
			||||||
 | 
							IsAdmin     bool // Current user is admin level.
 | 
				
			||||||
		HasAccess   bool
 | 
							HasAccess   bool
 | 
				
			||||||
		Repository  *models.Repository
 | 
							Repository  *models.Repository
 | 
				
			||||||
		Owner       *models.User
 | 
							Owner       *models.User
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -8,6 +8,7 @@ import (
 | 
				
			|||||||
	"github.com/Unknwon/macaron"
 | 
						"github.com/Unknwon/macaron"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"github.com/gogits/gogs/models"
 | 
						"github.com/gogits/gogs/models"
 | 
				
			||||||
 | 
						"github.com/gogits/gogs/modules/log"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func OrgAssignment(redirect bool, args ...bool) macaron.Handler {
 | 
					func OrgAssignment(redirect bool, args ...bool) macaron.Handler {
 | 
				
			||||||
@@ -35,6 +36,7 @@ func OrgAssignment(redirect bool, args ...bool) macaron.Handler {
 | 
				
			|||||||
			if err == models.ErrUserNotExist {
 | 
								if err == models.ErrUserNotExist {
 | 
				
			||||||
				ctx.Handle(404, "GetUserByName", err)
 | 
									ctx.Handle(404, "GetUserByName", err)
 | 
				
			||||||
			} else if redirect {
 | 
								} else if redirect {
 | 
				
			||||||
 | 
									log.Error(4, "GetUserByName", err)
 | 
				
			||||||
				ctx.Redirect("/")
 | 
									ctx.Redirect("/")
 | 
				
			||||||
			} else {
 | 
								} else {
 | 
				
			||||||
				ctx.Handle(500, "GetUserByName", err)
 | 
									ctx.Handle(500, "GetUserByName", err)
 | 
				
			||||||
@@ -52,17 +54,14 @@ func OrgAssignment(redirect bool, args ...bool) macaron.Handler {
 | 
				
			|||||||
			} else {
 | 
								} else {
 | 
				
			||||||
				if org.IsOrgMember(ctx.User.Id) {
 | 
									if org.IsOrgMember(ctx.User.Id) {
 | 
				
			||||||
					ctx.Org.IsMember = true
 | 
										ctx.Org.IsMember = true
 | 
				
			||||||
					// TODO: ctx.Org.IsAdminTeam
 | 
					 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		if (requireMember && !ctx.Org.IsMember) ||
 | 
							if (requireMember && !ctx.Org.IsMember) ||
 | 
				
			||||||
			(requireOwner && !ctx.Org.IsOwner) ||
 | 
								(requireOwner && !ctx.Org.IsOwner) {
 | 
				
			||||||
			(requireAdminTeam && !ctx.Org.IsAdminTeam) {
 | 
					 | 
				
			||||||
			ctx.Handle(404, "OrgAssignment", err)
 | 
								ctx.Handle(404, "OrgAssignment", err)
 | 
				
			||||||
			return
 | 
								return
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		ctx.Data["IsAdminTeam"] = ctx.Org.IsAdminTeam
 | 
					 | 
				
			||||||
		ctx.Data["IsOrganizationOwner"] = ctx.Org.IsOwner
 | 
							ctx.Data["IsOrganizationOwner"] = ctx.Org.IsOwner
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		ctx.Org.OrgLink = "/org/" + org.Name
 | 
							ctx.Org.OrgLink = "/org/" + org.Name
 | 
				
			||||||
@@ -76,6 +75,7 @@ func OrgAssignment(redirect bool, args ...bool) macaron.Handler {
 | 
				
			|||||||
				if err == models.ErrTeamNotExist {
 | 
									if err == models.ErrTeamNotExist {
 | 
				
			||||||
					ctx.Handle(404, "GetTeam", err)
 | 
										ctx.Handle(404, "GetTeam", err)
 | 
				
			||||||
				} else if redirect {
 | 
									} else if redirect {
 | 
				
			||||||
 | 
										log.Error(4, "GetTeam", err)
 | 
				
			||||||
					ctx.Redirect("/")
 | 
										ctx.Redirect("/")
 | 
				
			||||||
				} else {
 | 
									} else {
 | 
				
			||||||
					ctx.Handle(500, "GetTeam", err)
 | 
										ctx.Handle(500, "GetTeam", err)
 | 
				
			||||||
@@ -83,6 +83,12 @@ func OrgAssignment(redirect bool, args ...bool) macaron.Handler {
 | 
				
			|||||||
				return
 | 
									return
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			ctx.Data["Team"] = ctx.Org.Team
 | 
								ctx.Data["Team"] = ctx.Org.Team
 | 
				
			||||||
 | 
								ctx.Org.IsAdminTeam = ctx.Org.Team.IsOwnerTeam() || ctx.Org.Team.Authorize == models.ORG_ADMIN
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							ctx.Data["IsAdminTeam"] = ctx.Org.IsAdminTeam
 | 
				
			||||||
 | 
							if requireAdminTeam && !ctx.Org.IsAdminTeam {
 | 
				
			||||||
 | 
								ctx.Handle(404, "OrgAssignment", err)
 | 
				
			||||||
 | 
								return
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -59,6 +59,7 @@ func RepoAssignment(redirect bool, args ...bool) macaron.Handler {
 | 
				
			|||||||
				if err == models.ErrUserNotExist {
 | 
									if err == models.ErrUserNotExist {
 | 
				
			||||||
					ctx.Handle(404, "GetUserByName", err)
 | 
										ctx.Handle(404, "GetUserByName", err)
 | 
				
			||||||
				} else if redirect {
 | 
									} else if redirect {
 | 
				
			||||||
 | 
										log.Error(4, "GetUserByName", err)
 | 
				
			||||||
					ctx.Redirect("/")
 | 
										ctx.Redirect("/")
 | 
				
			||||||
				} else {
 | 
									} else {
 | 
				
			||||||
					ctx.Handle(500, "GetUserByName", err)
 | 
										ctx.Handle(500, "GetUserByName", err)
 | 
				
			||||||
@@ -84,7 +85,7 @@ func RepoAssignment(redirect bool, args ...bool) macaron.Handler {
 | 
				
			|||||||
			ctx.Repo.IsTrueOwner = true
 | 
								ctx.Repo.IsTrueOwner = true
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// get repository
 | 
							// Get repository.
 | 
				
			||||||
		repo, err := models.GetRepositoryByName(u.Id, repoName)
 | 
							repo, err := models.GetRepositoryByName(u.Id, repoName)
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
			if err == models.ErrRepoNotExist {
 | 
								if err == models.ErrRepoNotExist {
 | 
				
			||||||
@@ -102,8 +103,22 @@ func RepoAssignment(redirect bool, args ...bool) macaron.Handler {
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// Check if the mirror repository owner(mirror repository doesn't have access).
 | 
							// Check if the mirror repository owner(mirror repository doesn't have access).
 | 
				
			||||||
		if ctx.IsSigned && !ctx.Repo.IsOwner && repo.OwnerId == ctx.User.Id {
 | 
							if ctx.IsSigned && !ctx.Repo.IsOwner {
 | 
				
			||||||
			ctx.Repo.IsOwner = true
 | 
								if repo.OwnerId == ctx.User.Id {
 | 
				
			||||||
 | 
									ctx.Repo.IsOwner = true
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								// Check if current user has admin permission to repository.
 | 
				
			||||||
 | 
								if u.IsOrganization() {
 | 
				
			||||||
 | 
									auth, err := models.GetHighestAuthorize(u.Id, ctx.User.Id, 0, repo.Id)
 | 
				
			||||||
 | 
									if err != nil {
 | 
				
			||||||
 | 
										ctx.Handle(500, "GetHighestAuthorize", err)
 | 
				
			||||||
 | 
										return
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									if auth == models.ORG_ADMIN {
 | 
				
			||||||
 | 
										ctx.Repo.IsOwner = true
 | 
				
			||||||
 | 
										ctx.Repo.IsAdmin = true
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// Check access.
 | 
							// Check access.
 | 
				
			||||||
@@ -281,7 +296,7 @@ func RepoAssignment(redirect bool, args ...bool) macaron.Handler {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
func RequireTrueOwner() macaron.Handler {
 | 
					func RequireTrueOwner() macaron.Handler {
 | 
				
			||||||
	return func(ctx *Context) {
 | 
						return func(ctx *Context) {
 | 
				
			||||||
		if !ctx.Repo.IsTrueOwner {
 | 
							if !ctx.Repo.IsTrueOwner && !ctx.Repo.IsAdmin {
 | 
				
			||||||
			if !ctx.IsSigned {
 | 
								if !ctx.IsSigned {
 | 
				
			||||||
				ctx.SetCookie("redirect_to", "/"+url.QueryEscape(ctx.Req.RequestURI))
 | 
									ctx.SetCookie("redirect_to", "/"+url.QueryEscape(ctx.Req.RequestURI))
 | 
				
			||||||
				ctx.Redirect("/user/login")
 | 
									ctx.Redirect("/user/login")
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1298,27 +1298,33 @@ The register and sign-in page style
 | 
				
			|||||||
.repo-setting-zone {
 | 
					.repo-setting-zone {
 | 
				
			||||||
  padding: 30px;
 | 
					  padding: 30px;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					#team-members-list,
 | 
				
			||||||
#repo-collab-list {
 | 
					#repo-collab-list {
 | 
				
			||||||
  list-style: none;
 | 
					  list-style: none;
 | 
				
			||||||
  padding: 10px 0 5px 0;
 | 
					  padding: 10px 0 5px 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					#team-members-list li.collab,
 | 
				
			||||||
#repo-collab-list li.collab {
 | 
					#repo-collab-list li.collab {
 | 
				
			||||||
  clear: both;
 | 
					  clear: both;
 | 
				
			||||||
  height: 50px;
 | 
					  height: 50px;
 | 
				
			||||||
  padding: 0 15px 0 15px;
 | 
					  padding: 0 15px 0 15px;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					#team-members-list a.member,
 | 
				
			||||||
#repo-collab-list a.member {
 | 
					#repo-collab-list a.member {
 | 
				
			||||||
  color: #444;
 | 
					  color: #444;
 | 
				
			||||||
  height: 50px;
 | 
					  height: 50px;
 | 
				
			||||||
  line-height: 50px;
 | 
					  line-height: 50px;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					#team-members-list a.member:hover,
 | 
				
			||||||
#repo-collab-list a.member:hover {
 | 
					#repo-collab-list a.member:hover {
 | 
				
			||||||
  color: #4183C4;
 | 
					  color: #4183C4;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					#team-members-list .avatar,
 | 
				
			||||||
#repo-collab-list .avatar {
 | 
					#repo-collab-list .avatar {
 | 
				
			||||||
  margin-right: 1em;
 | 
					  margin-right: 1em;
 | 
				
			||||||
  width: 40px;
 | 
					  width: 40px;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					#team-members-list .remove-collab,
 | 
				
			||||||
#repo-collab-list .remove-collab {
 | 
					#repo-collab-list .remove-collab {
 | 
				
			||||||
  color: #DD4B39;
 | 
					  color: #DD4B39;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -1871,3 +1877,14 @@ textarea#issue-add-content {
 | 
				
			|||||||
#org-team-card .panel-footer {
 | 
					#org-team-card .panel-footer {
 | 
				
			||||||
  padding: 10px 20px;
 | 
					  padding: 10px 20px;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					#team-members-list .panel-body .search {
 | 
				
			||||||
 | 
					  padding: 4px 0 10px 10px;
 | 
				
			||||||
 | 
					  border-bottom: 1px solid #dddddd;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					#team-members-list li.collab {
 | 
				
			||||||
 | 
					  padding-top: 10px !important;
 | 
				
			||||||
 | 
					  border-bottom: 1px solid #dddddd;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					#team-members-list li.collab:last-child {
 | 
				
			||||||
 | 
					  border-bottom: 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -351,6 +351,41 @@ function initInvite() {
 | 
				
			|||||||
    });
 | 
					    });
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function initOrgTeamCreate() {
 | 
				
			||||||
 | 
					    // Delete team.
 | 
				
			||||||
 | 
					    $('#org-team-delete').click(function (e) {
 | 
				
			||||||
 | 
					        if (!confirm('This team is going to be deleted, do you want to continue?')) {
 | 
				
			||||||
 | 
					            e.preventDefault();
 | 
				
			||||||
 | 
					            return true;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        var $form = $('#team-create-form')
 | 
				
			||||||
 | 
					        $form.attr('action', $form.data('delete-url'));
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function initTeamMembersList() {
 | 
				
			||||||
 | 
					    // Add team member.
 | 
				
			||||||
 | 
					    var $ul = $('#org-team-members-list');
 | 
				
			||||||
 | 
					    $('#org-team-members-add').on('keyup', function () {
 | 
				
			||||||
 | 
					        var $this = $(this);
 | 
				
			||||||
 | 
					        if (!$this.val()) {
 | 
				
			||||||
 | 
					            $ul.toggleHide();
 | 
				
			||||||
 | 
					            return;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        Gogs.searchUsers($this.val(), $ul);
 | 
				
			||||||
 | 
					    }).on('focus', function () {
 | 
				
			||||||
 | 
					        if (!$(this).val()) {
 | 
				
			||||||
 | 
					            $ul.toggleHide();
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            $ul.toggleShow();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }).next().next().find('ul').on("click", 'li', function () {
 | 
				
			||||||
 | 
					        $('#org-team-members-add').val($(this).text());
 | 
				
			||||||
 | 
					        $ul.toggleHide();
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
$(document).ready(function () {
 | 
					$(document).ready(function () {
 | 
				
			||||||
    initCore();
 | 
					    initCore();
 | 
				
			||||||
    if ($('#user-profile-setting').length) {
 | 
					    if ($('#user-profile-setting').length) {
 | 
				
			||||||
@@ -368,6 +403,12 @@ $(document).ready(function () {
 | 
				
			|||||||
    if ($('#invite-box').length) {
 | 
					    if ($('#invite-box').length) {
 | 
				
			||||||
        initInvite();
 | 
					        initInvite();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    if ($('#team-create-form').length) {
 | 
				
			||||||
 | 
					        initOrgTeamCreate();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if ($('#team-members-list').length) {
 | 
				
			||||||
 | 
					        initTeamMembersList();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Tabs('#dashboard-sidebar-menu');
 | 
					    Tabs('#dashboard-sidebar-menu');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -196,4 +196,19 @@
 | 
				
			|||||||
	.panel-footer {
 | 
						.panel-footer {
 | 
				
			||||||
		padding: 10px 20px;
 | 
							padding: 10px 20px;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					#team-members-list {
 | 
				
			||||||
 | 
						.panel-body .search {
 | 
				
			||||||
 | 
							padding: 4px 0 10px 10px;
 | 
				
			||||||
 | 
							border-bottom: 1px solid #dddddd;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					#team-members-list {
 | 
				
			||||||
 | 
						li.collab {
 | 
				
			||||||
 | 
							padding-top: 10px !important;
 | 
				
			||||||
 | 
							border-bottom: 1px solid #dddddd;
 | 
				
			||||||
 | 
							&:last-child {
 | 
				
			||||||
 | 
								border-bottom: 0;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -426,6 +426,7 @@ border-top-right-radius: .25em;
 | 
				
			|||||||
.repo-setting-zone {
 | 
					.repo-setting-zone {
 | 
				
			||||||
	padding: 30px;
 | 
						padding: 30px;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					#team-members-list,
 | 
				
			||||||
#repo-collab-list {
 | 
					#repo-collab-list {
 | 
				
			||||||
	list-style: none;
 | 
						list-style: none;
 | 
				
			||||||
	padding: 10px 0 5px 0;
 | 
						padding: 10px 0 5px 0;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -82,7 +82,12 @@ func MembersAction(ctx *middleware.Context) {
 | 
				
			|||||||
		})
 | 
							})
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	ctx.Redirect(ctx.Org.OrgLink + "/members")
 | 
					
 | 
				
			||||||
 | 
						if ctx.Params(":action") != "leave" {
 | 
				
			||||||
 | 
							ctx.Redirect(ctx.Org.OrgLink + "/members")
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							ctx.Redirect("/")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func Invitation(ctx *middleware.Context) {
 | 
					func Invitation(ctx *middleware.Context) {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -5,6 +5,8 @@
 | 
				
			|||||||
package org
 | 
					package org
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
 | 
						"github.com/Unknwon/com"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"github.com/gogits/gogs/models"
 | 
						"github.com/gogits/gogs/models"
 | 
				
			||||||
	"github.com/gogits/gogs/modules/auth"
 | 
						"github.com/gogits/gogs/modules/auth"
 | 
				
			||||||
	"github.com/gogits/gogs/modules/base"
 | 
						"github.com/gogits/gogs/modules/base"
 | 
				
			||||||
@@ -39,23 +41,71 @@ func Teams(ctx *middleware.Context) {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func TeamsAction(ctx *middleware.Context) {
 | 
					func TeamsAction(ctx *middleware.Context) {
 | 
				
			||||||
 | 
						uid := com.StrTo(ctx.Query("uid")).MustInt64()
 | 
				
			||||||
 | 
						if uid == 0 {
 | 
				
			||||||
 | 
							ctx.Redirect(ctx.Org.OrgLink + "/teams")
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						page := ctx.Query("page")
 | 
				
			||||||
	var err error
 | 
						var err error
 | 
				
			||||||
	switch ctx.Params(":action") {
 | 
						switch ctx.Params(":action") {
 | 
				
			||||||
	case "join":
 | 
						case "join":
 | 
				
			||||||
 | 
							if !ctx.Org.IsOwner {
 | 
				
			||||||
 | 
								ctx.Error(404)
 | 
				
			||||||
 | 
								return
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
		err = ctx.Org.Team.AddMember(ctx.User.Id)
 | 
							err = ctx.Org.Team.AddMember(ctx.User.Id)
 | 
				
			||||||
	case "leave":
 | 
						case "leave":
 | 
				
			||||||
		err = ctx.Org.Team.RemoveMember(ctx.User.Id)
 | 
							err = ctx.Org.Team.RemoveMember(ctx.User.Id)
 | 
				
			||||||
 | 
						case "remove":
 | 
				
			||||||
 | 
							if !ctx.Org.IsOwner {
 | 
				
			||||||
 | 
								ctx.Error(404)
 | 
				
			||||||
 | 
								return
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							err = ctx.Org.Team.RemoveMember(uid)
 | 
				
			||||||
 | 
							page = "team"
 | 
				
			||||||
 | 
						case "add":
 | 
				
			||||||
 | 
							if !ctx.Org.IsOwner {
 | 
				
			||||||
 | 
								ctx.Error(404)
 | 
				
			||||||
 | 
								return
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							uname := ctx.Query("uname")
 | 
				
			||||||
 | 
							var u *models.User
 | 
				
			||||||
 | 
							u, err = models.GetUserByName(uname)
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								if err == models.ErrUserNotExist {
 | 
				
			||||||
 | 
									ctx.Flash.Error(ctx.Tr("form.user_not_exist"))
 | 
				
			||||||
 | 
									ctx.Redirect(ctx.Org.OrgLink + "/teams/" + ctx.Org.Team.LowerName)
 | 
				
			||||||
 | 
								} else {
 | 
				
			||||||
 | 
									ctx.Handle(500, " GetUserByName", err)
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								return
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							err = ctx.Org.Team.AddMember(u.Id)
 | 
				
			||||||
 | 
							page = "team"
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		log.Error(4, "Action(%s): %v", ctx.Params(":action"), err)
 | 
							if err == models.ErrLastOrgOwner {
 | 
				
			||||||
		ctx.JSON(200, map[string]interface{}{
 | 
								ctx.Flash.Error(ctx.Tr("form.last_org_owner"))
 | 
				
			||||||
			"ok":  false,
 | 
							} else {
 | 
				
			||||||
			"err": err.Error(),
 | 
								log.Error(4, "Action(%s): %v", ctx.Params(":action"), err)
 | 
				
			||||||
		})
 | 
								ctx.JSON(200, map[string]interface{}{
 | 
				
			||||||
		return
 | 
									"ok":  false,
 | 
				
			||||||
 | 
									"err": err.Error(),
 | 
				
			||||||
 | 
								})
 | 
				
			||||||
 | 
								return
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						switch page {
 | 
				
			||||||
 | 
						case "team":
 | 
				
			||||||
 | 
							ctx.Redirect(ctx.Org.OrgLink + "/teams/" + ctx.Org.Team.LowerName)
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							ctx.Redirect(ctx.Org.OrgLink + "/teams")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	ctx.Redirect(ctx.Org.OrgLink + "/teams")
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func NewTeam(ctx *middleware.Context) {
 | 
					func NewTeam(ctx *middleware.Context) {
 | 
				
			||||||
@@ -116,13 +166,76 @@ func NewTeamPost(ctx *middleware.Context, form auth.CreateTeamForm) {
 | 
				
			|||||||
	ctx.Redirect(ctx.Org.OrgLink + "/teams/" + t.LowerName)
 | 
						ctx.Redirect(ctx.Org.OrgLink + "/teams/" + t.LowerName)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func EditTeam(ctx *middleware.Context) {
 | 
					func TeamMembers(ctx *middleware.Context) {
 | 
				
			||||||
	ctx.Data["Title"] = "Organization " + ctx.Params(":org") + " Edit Team"
 | 
					 | 
				
			||||||
	ctx.HTML(200, "org/edit_team")
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func SingleTeam(ctx *middleware.Context) {
 | 
					 | 
				
			||||||
	ctx.Data["Title"] = ctx.Org.Team.Name
 | 
						ctx.Data["Title"] = ctx.Org.Team.Name
 | 
				
			||||||
	ctx.Data["PageIsOrgTeams"] = true
 | 
						ctx.Data["PageIsOrgTeams"] = true
 | 
				
			||||||
 | 
						if err := ctx.Org.Team.GetMembers(); err != nil {
 | 
				
			||||||
 | 
							ctx.Handle(500, "GetMembers", err)
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	ctx.HTML(200, TEAM_MEMBERS)
 | 
						ctx.HTML(200, TEAM_MEMBERS)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func EditTeam(ctx *middleware.Context) {
 | 
				
			||||||
 | 
						ctx.Data["Title"] = ctx.Org.Organization.FullName
 | 
				
			||||||
 | 
						ctx.Data["PageIsOrgTeams"] = true
 | 
				
			||||||
 | 
						ctx.Data["team_name"] = ctx.Org.Team.Name
 | 
				
			||||||
 | 
						ctx.Data["desc"] = ctx.Org.Team.Description
 | 
				
			||||||
 | 
						ctx.HTML(200, TEAM_NEW)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func EditTeamPost(ctx *middleware.Context, form auth.CreateTeamForm) {
 | 
				
			||||||
 | 
						t := ctx.Org.Team
 | 
				
			||||||
 | 
						ctx.Data["Title"] = ctx.Org.Organization.FullName
 | 
				
			||||||
 | 
						ctx.Data["PageIsOrgTeams"] = true
 | 
				
			||||||
 | 
						ctx.Data["team_name"] = t.Name
 | 
				
			||||||
 | 
						ctx.Data["desc"] = t.Description
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if ctx.HasError() {
 | 
				
			||||||
 | 
							ctx.HTML(200, TEAM_NEW)
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						isAuthChanged := false
 | 
				
			||||||
 | 
						if !t.IsOwnerTeam() {
 | 
				
			||||||
 | 
							// Validate permission level.
 | 
				
			||||||
 | 
							var auth models.AuthorizeType
 | 
				
			||||||
 | 
							switch form.Permission {
 | 
				
			||||||
 | 
							case "read":
 | 
				
			||||||
 | 
								auth = models.ORG_READABLE
 | 
				
			||||||
 | 
							case "write":
 | 
				
			||||||
 | 
								auth = models.ORG_WRITABLE
 | 
				
			||||||
 | 
							case "admin":
 | 
				
			||||||
 | 
								auth = models.ORG_ADMIN
 | 
				
			||||||
 | 
							default:
 | 
				
			||||||
 | 
								ctx.Error(401)
 | 
				
			||||||
 | 
								return
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							t.Name = form.TeamName
 | 
				
			||||||
 | 
							if t.Authorize != auth {
 | 
				
			||||||
 | 
								isAuthChanged = true
 | 
				
			||||||
 | 
								t.Authorize = auth
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						t.Description = form.Description
 | 
				
			||||||
 | 
						if err := models.UpdateTeam(t, isAuthChanged); err != nil {
 | 
				
			||||||
 | 
							if err == models.ErrTeamNameIllegal {
 | 
				
			||||||
 | 
								ctx.Data["Err_TeamName"] = true
 | 
				
			||||||
 | 
								ctx.RenderWithErr(ctx.Tr("form.illegal_team_name"), TEAM_NEW, &form)
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								ctx.Handle(500, "UpdateTeam", err)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						ctx.Redirect(ctx.Org.OrgLink + "/teams/" + t.LowerName)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func DeleteTeam(ctx *middleware.Context) {
 | 
				
			||||||
 | 
						if err := models.DeleteTeam(ctx.Org.Team); err != nil {
 | 
				
			||||||
 | 
							ctx.Handle(500, "DeleteTeam", err)
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						ctx.Flash.Success(ctx.Tr("org.teams.delete_team_success"))
 | 
				
			||||||
 | 
						ctx.Redirect(ctx.Org.OrgLink + "/teams")
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -56,7 +56,12 @@ func SettingsPost(ctx *middleware.Context, form auth.RepoSettingForm) {
 | 
				
			|||||||
				ctx.RenderWithErr(ctx.Tr("form.repo_name_been_taken"), SETTINGS_OPTIONS, nil)
 | 
									ctx.RenderWithErr(ctx.Tr("form.repo_name_been_taken"), SETTINGS_OPTIONS, nil)
 | 
				
			||||||
				return
 | 
									return
 | 
				
			||||||
			} else if err = models.ChangeRepositoryName(ctx.Repo.Owner.Name, ctx.Repo.Repository.Name, newRepoName); err != nil {
 | 
								} else if err = models.ChangeRepositoryName(ctx.Repo.Owner.Name, ctx.Repo.Repository.Name, newRepoName); err != nil {
 | 
				
			||||||
				ctx.Handle(500, "ChangeRepositoryName", err)
 | 
									if err == models.ErrRepoNameIllegal {
 | 
				
			||||||
 | 
										ctx.Data["Err_RepoName"] = true
 | 
				
			||||||
 | 
										ctx.RenderWithErr(ctx.Tr("form.illegal_repo_name"), SETTINGS_OPTIONS, nil)
 | 
				
			||||||
 | 
									} else {
 | 
				
			||||||
 | 
										ctx.Handle(500, "ChangeRepositoryName", err)
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
				return
 | 
									return
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			log.Trace("Repository name changed: %s/%s -> %s", ctx.Repo.Owner.Name, ctx.Repo.Repository.Name, newRepoName)
 | 
								log.Trace("Repository name changed: %s/%s -> %s", ctx.Repo.Owner.Name, ctx.Repo.Repository.Name, newRepoName)
 | 
				
			||||||
@@ -185,9 +190,24 @@ func SettingsCollaboration(ctx *middleware.Context) {
 | 
				
			|||||||
	// Delete collaborator.
 | 
						// Delete collaborator.
 | 
				
			||||||
	remove := strings.ToLower(ctx.Query("remove"))
 | 
						remove := strings.ToLower(ctx.Query("remove"))
 | 
				
			||||||
	if len(remove) > 0 && remove != ctx.Repo.Owner.LowerName {
 | 
						if len(remove) > 0 && remove != ctx.Repo.Owner.LowerName {
 | 
				
			||||||
		if err := models.DeleteAccess(&models.Access{UserName: remove, RepoName: repoLink}); err != nil {
 | 
							needDelete := true
 | 
				
			||||||
			ctx.Handle(500, "DeleteAccess", err)
 | 
							if ctx.User.IsOrganization() {
 | 
				
			||||||
			return
 | 
								// Check if user belongs to a team that has access to this repository.
 | 
				
			||||||
 | 
								auth, err := models.GetHighestAuthorize(ctx.Repo.Owner.Id, ctx.User.Id, 0, ctx.Repo.Repository.Id)
 | 
				
			||||||
 | 
								if err != nil {
 | 
				
			||||||
 | 
									ctx.Handle(500, "GetHighestAuthorize", err)
 | 
				
			||||||
 | 
									return
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								if auth > 0 {
 | 
				
			||||||
 | 
									needDelete = false
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if needDelete {
 | 
				
			||||||
 | 
								if err := models.DeleteAccess(&models.Access{UserName: remove, RepoName: repoLink}); err != nil {
 | 
				
			||||||
 | 
									ctx.Handle(500, "DeleteAccess", err)
 | 
				
			||||||
 | 
									return
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		ctx.Flash.Success(ctx.Tr("repo.settings.remove_collaborator_success"))
 | 
							ctx.Flash.Success(ctx.Tr("repo.settings.remove_collaborator_success"))
 | 
				
			||||||
		ctx.Redirect(ctx.Repo.RepoLink + "/settings/collaboration")
 | 
							ctx.Redirect(ctx.Repo.RepoLink + "/settings/collaboration")
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1 +1 @@
 | 
				
			|||||||
0.4.7.0823 Alpha
 | 
					0.4.7.0824 Alpha
 | 
				
			||||||
@@ -18,6 +18,7 @@
 | 
				
			|||||||
	</div>
 | 
						</div>
 | 
				
			||||||
</div>
 | 
					</div>
 | 
				
			||||||
<div class="container">
 | 
					<div class="container">
 | 
				
			||||||
 | 
						{{$isMember := .Org.IsOrgMember $.SignedUser.Id}}
 | 
				
			||||||
    <div id="org-home-repo-list" class="left grid-2-3">
 | 
					    <div id="org-home-repo-list" class="left grid-2-3">
 | 
				
			||||||
        <div class="clear">
 | 
					        <div class="clear">
 | 
				
			||||||
        	{{if .IsOrganizationOwner}}
 | 
					        	{{if .IsOrganizationOwner}}
 | 
				
			||||||
@@ -26,6 +27,7 @@
 | 
				
			|||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
        <div id="org-repo-list">
 | 
					        <div id="org-repo-list">
 | 
				
			||||||
			{{range .Repos}}
 | 
								{{range .Repos}}
 | 
				
			||||||
 | 
									{{if or $isMember (not .IsPrivate)}}
 | 
				
			||||||
				<div class="org-repo-item">
 | 
									<div class="org-repo-item">
 | 
				
			||||||
                    <ul class="org-repo-status right">
 | 
					                    <ul class="org-repo-status right">
 | 
				
			||||||
                        <li><i class="octicon octicon-star"></i> {{.NumStars}}</li>
 | 
					                        <li><i class="octicon octicon-star"></i> {{.NumStars}}</li>
 | 
				
			||||||
@@ -35,6 +37,7 @@
 | 
				
			|||||||
					<p class="org-repo-description">{{.Description}}</p>
 | 
										<p class="org-repo-description">{{.Description}}</p>
 | 
				
			||||||
					<p class="org-repo-updated">{{$.i18n.Tr "org.repo_updated"}} {{TimeSince .Updated $.i18n.Lang}}</p>
 | 
										<p class="org-repo-updated">{{$.i18n.Tr "org.repo_updated"}} {{TimeSince .Updated $.i18n.Lang}}</p>
 | 
				
			||||||
				</div>
 | 
									</div>
 | 
				
			||||||
 | 
									{{end}}
 | 
				
			||||||
			{{end}}
 | 
								{{end}}
 | 
				
			||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
@@ -42,12 +45,16 @@
 | 
				
			|||||||
    	<div class="org-sidebar">
 | 
					    	<div class="org-sidebar">
 | 
				
			||||||
	    	<div class="panel panel-radius">
 | 
						    	<div class="panel panel-radius">
 | 
				
			||||||
	    		<div class="panel-header">
 | 
						    		<div class="panel-header">
 | 
				
			||||||
 | 
						    			{{if $isMember}}
 | 
				
			||||||
	    			<a class="text-grey right" href="/org/{{.Org.LowerName}}/members"><strong>{{.Org.NumMembers}}</strong><span class="octicon octicon-chevron-right"></span></a>
 | 
						    			<a class="text-grey right" href="/org/{{.Org.LowerName}}/members"><strong>{{.Org.NumMembers}}</strong><span class="octicon octicon-chevron-right"></span></a>
 | 
				
			||||||
 | 
						    			{{end}}
 | 
				
			||||||
	    			<strong>{{.i18n.Tr "org.people"}}</strong>
 | 
						    			<strong>{{.i18n.Tr "org.people"}}</strong>
 | 
				
			||||||
	    		</div>
 | 
						    		</div>
 | 
				
			||||||
	    		<div class="panel-body member-avatar-group">
 | 
						    		<div class="panel-body member-avatar-group">
 | 
				
			||||||
	    			{{range .Members}}
 | 
						    			{{range .Members}}
 | 
				
			||||||
	    			<a href="/{{.Name}}" title="{{.Name}}"><img src="{{.AvatarLink}}"></a>
 | 
											{{if or $isMember (.IsPublicMember $.Org.Id)}}
 | 
				
			||||||
 | 
						    				<a href="/{{.Name}}" title="{{.Name}}"><img src="{{.AvatarLink}}"></a>
 | 
				
			||||||
 | 
						    				{{end}}
 | 
				
			||||||
	    			{{end}}
 | 
						    			{{end}}
 | 
				
			||||||
	    		</div>
 | 
						    		</div>
 | 
				
			||||||
	    		{{if .IsOrganizationOwner}}
 | 
						    		{{if .IsOrganizationOwner}}
 | 
				
			||||||
@@ -56,6 +63,7 @@
 | 
				
			|||||||
	    		</div>
 | 
						    		</div>
 | 
				
			||||||
	    		{{end}}
 | 
						    		{{end}}
 | 
				
			||||||
	    	</div>
 | 
						    	</div>
 | 
				
			||||||
 | 
						    	{{if $isMember}}
 | 
				
			||||||
	    	<br>
 | 
						    	<br>
 | 
				
			||||||
	    	<div class="panel panel-radius">
 | 
						    	<div class="panel panel-radius">
 | 
				
			||||||
	    		<div class="panel-header">
 | 
						    		<div class="panel-header">
 | 
				
			||||||
@@ -76,9 +84,9 @@
 | 
				
			|||||||
	    		<div class="panel-footer">
 | 
						    		<div class="panel-footer">
 | 
				
			||||||
	    			<a class="btn btn-medium btn-blue btn-link btn-radius" href="/org/{{$.Org.LowerName}}/teams/new">{{.i18n.Tr "org.create_new_team"}}</a>
 | 
						    			<a class="btn btn-medium btn-blue btn-link btn-radius" href="/org/{{$.Org.LowerName}}/teams/new">{{.i18n.Tr "org.create_new_team"}}</a>
 | 
				
			||||||
	    		</div>
 | 
						    		</div>
 | 
				
			||||||
 | 
					 | 
				
			||||||
	    		{{end}}
 | 
						    		{{end}}
 | 
				
			||||||
	    	</div>
 | 
						    	</div>
 | 
				
			||||||
 | 
						    	{{end}}
 | 
				
			||||||
    	</div>
 | 
					    	</div>
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
</div>
 | 
					</div>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -6,7 +6,7 @@
 | 
				
			|||||||
		{{template "ng/base/alert" .}}
 | 
							{{template "ng/base/alert" .}}
 | 
				
			||||||
	</div>
 | 
						</div>
 | 
				
			||||||
	<div class="org-toolbar clear">
 | 
						<div class="org-toolbar clear">
 | 
				
			||||||
		{{if .IsAdminTeam}}
 | 
							{{if .IsOrganizationOwner}}
 | 
				
			||||||
        <a class="btn btn-green btn-large btn-link btn-radius right" href="{{.OrgLink}}/invitations/new"><i class="octicon octicon-repo-create"></i> {{.i18n.Tr "org.invite_someone"}}</a>
 | 
					        <a class="btn btn-green btn-large btn-link btn-radius right" href="{{.OrgLink}}/invitations/new"><i class="octicon octicon-repo-create"></i> {{.i18n.Tr "org.invite_someone"}}</a>
 | 
				
			||||||
		{{end}}
 | 
							{{end}}
 | 
				
			||||||
	</div>
 | 
						</div>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2,7 +2,8 @@
 | 
				
			|||||||
{{template "ng/base/header" .}}
 | 
					{{template "ng/base/header" .}}
 | 
				
			||||||
{{template "org/base/header" .}}
 | 
					{{template "org/base/header" .}}
 | 
				
			||||||
<div id="setting-wrapper" class="main-wrapper">
 | 
					<div id="setting-wrapper" class="main-wrapper">
 | 
				
			||||||
    <div id="org-setting" class="container clear">
 | 
					    <div id="team-members-list" class="container clear">
 | 
				
			||||||
 | 
							{{template "ng/base/alert" .}}
 | 
				
			||||||
		{{template "org/team/sidebar" .}}
 | 
							{{template "org/team/sidebar" .}}
 | 
				
			||||||
		<div class="grid-2-3 left">
 | 
							<div class="grid-2-3 left">
 | 
				
			||||||
			<div class="setting-content">
 | 
								<div class="setting-content">
 | 
				
			||||||
@@ -10,6 +11,32 @@
 | 
				
			|||||||
					<div class="panel-header">
 | 
										<div class="panel-header">
 | 
				
			||||||
						{{.i18n.Tr "org.teams.members"}}
 | 
											{{.i18n.Tr "org.teams.members"}}
 | 
				
			||||||
					</div>
 | 
										</div>
 | 
				
			||||||
 | 
					                    <ul class="panel-body setting-list" id="team-members-list">
 | 
				
			||||||
 | 
					                    	{{if .IsOrganizationOwner}}
 | 
				
			||||||
 | 
											<li class="search">
 | 
				
			||||||
 | 
								                <form class="form form-align" action="{{$.OrgLink}}/teams/{{$.Team.LowerName}}/action/add" id="repo-collab-form">
 | 
				
			||||||
 | 
								                    {{.CsrfTokenHtml}}
 | 
				
			||||||
 | 
								                    <input type="hidden" name="uid" value="{{.SignedUser.Id}}">
 | 
				
			||||||
 | 
					                                <input class="ipt ipt-large ipt-radius" id="org-team-members-add" name="uname" autocomplete="off" required />
 | 
				
			||||||
 | 
					                                <button class="btn btn-blue btn-large btn-radius">{{.i18n.Tr "org.teams.add_team_member"}}</button>
 | 
				
			||||||
 | 
													<div class="repo-user-list-block">
 | 
				
			||||||
 | 
														<ul class="menu-down-show menu-vertical menu-radius switching-list user-list" id="org-team-members-list"></ul>
 | 
				
			||||||
 | 
													</div>
 | 
				
			||||||
 | 
								                </form>
 | 
				
			||||||
 | 
											</li>
 | 
				
			||||||
 | 
											{{end}}
 | 
				
			||||||
 | 
					                		{{range .Team.Members}}
 | 
				
			||||||
 | 
					                		<li class="collab">
 | 
				
			||||||
 | 
					                			{{if $.IsOrganizationOwner}}
 | 
				
			||||||
 | 
												<a class="btn btn-small btn-red btn-radius right" href="{{$.OrgLink}}/teams/{{$.Team.LowerName}}/action/remove?uid={{.Id}}">{{$.i18n.Tr "org.members.remove"}}</a>
 | 
				
			||||||
 | 
												{{end}}
 | 
				
			||||||
 | 
												<a class="member" href="/{{.Name}}">
 | 
				
			||||||
 | 
												    <img alt="{{.Name}}" class="pull-left avatar" src="{{.AvatarLink}}">
 | 
				
			||||||
 | 
												    <strong>{{.FullName}}</strong> ({{.Name}})
 | 
				
			||||||
 | 
												</a>
 | 
				
			||||||
 | 
					                		</li>
 | 
				
			||||||
 | 
					                		{{end}}
 | 
				
			||||||
 | 
					                    </ul>
 | 
				
			||||||
				</div>
 | 
									</div>
 | 
				
			||||||
			</div>
 | 
								</div>
 | 
				
			||||||
		</div>
 | 
							</div>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2,16 +2,21 @@
 | 
				
			|||||||
{{template "ng/base/header" .}}
 | 
					{{template "ng/base/header" .}}
 | 
				
			||||||
{{template "org/base/header" .}}
 | 
					{{template "org/base/header" .}}
 | 
				
			||||||
<div id="repo-wrapper">
 | 
					<div id="repo-wrapper">
 | 
				
			||||||
    <form id="team-create-form" class="form form-align panel panel-radius" action="{{.OrgLink}}/teams/new" method="post">
 | 
					    <form id="team-create-form" class="form form-align panel panel-radius" action="{{if .PageIsOrgTeamsNew}}{{.OrgLink}}/teams/new{{else}}{{.OrgLink}}/teams/{{.Team.LowerName}}/edit{{end}}" data-delete-url="{{.OrgLink}}/teams/{{.Team.LowerName}}/delete" method="post">
 | 
				
			||||||
        {{.CsrfTokenHtml}}
 | 
					        {{.CsrfTokenHtml}}
 | 
				
			||||||
        <div class="panel-header">
 | 
					        <div class="panel-header">
 | 
				
			||||||
            <h2>{{.i18n.Tr "org.create_new_team"}}</h2>
 | 
					            <h2>
 | 
				
			||||||
 | 
					                {{if .PageIsOrgTeamsNew}}{{.i18n.Tr "org.create_new_team"}}{{else}}{{.i18n.Tr "org.teams.settings"}}{{end}}
 | 
				
			||||||
 | 
					            </h2>
 | 
				
			||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
        <div class="panel-content">
 | 
					        <div class="panel-content">
 | 
				
			||||||
            {{template "ng/base/alert" .}}
 | 
					            {{template "ng/base/alert" .}}
 | 
				
			||||||
            <div class="field">
 | 
					            <div class="field">
 | 
				
			||||||
                <label class="req" for="team-name">{{.i18n.Tr "org.team_name"}}</label>
 | 
					                <label class="req" for="team-name">{{.i18n.Tr "org.team_name"}}</label>
 | 
				
			||||||
                <input class="ipt ipt-large ipt-radius {{if .Err_TeamName}}ipt-error{{end}}" id="team-name" name="team_name" value="{{.team_name}}" required />
 | 
					                {{if eq .Team.LowerName "owners"}}
 | 
				
			||||||
 | 
					                <input type="hidden" name="team_name" value="{{.team_name}}">
 | 
				
			||||||
 | 
					                {{end}}
 | 
				
			||||||
 | 
					                <input class="ipt ipt-large ipt-radius {{if .Err_TeamName}}ipt-error{{end}}" id="team-name" name="team_name" value="{{.team_name}}" required {{if eq .Team.LowerName "owners"}}disabled{{end}} />
 | 
				
			||||||
                <span class="form-label"></span>
 | 
					                <span class="form-label"></span>
 | 
				
			||||||
                <span class="help">{{.i18n.Tr "org.team_name_helper"}}</span>
 | 
					                <span class="help">{{.i18n.Tr "org.team_name_helper"}}</span>
 | 
				
			||||||
            </div>
 | 
					            </div>
 | 
				
			||||||
@@ -21,6 +26,7 @@
 | 
				
			|||||||
                <span class="form-label"></span>
 | 
					                <span class="form-label"></span>
 | 
				
			||||||
                <span class="help">{{.i18n.Tr "org.team_desc_helper"}}</span>
 | 
					                <span class="help">{{.i18n.Tr "org.team_desc_helper"}}</span>
 | 
				
			||||||
            </div>
 | 
					            </div>
 | 
				
			||||||
 | 
					            {{if not (eq .Team.LowerName "owners")}}
 | 
				
			||||||
            <div class="field">
 | 
					            <div class="field">
 | 
				
			||||||
                <h4 class="text-center">{{.i18n.Tr "org.team_permission_desc"}}</h4>
 | 
					                <h4 class="text-center">{{.i18n.Tr "org.team_permission_desc"}}</h4>
 | 
				
			||||||
                <label></label>
 | 
					                <label></label>
 | 
				
			||||||
@@ -37,10 +43,19 @@
 | 
				
			|||||||
                <p class="text-grey note">{{.i18n.Tr "org.teams.admin_access_helper"}}</p>
 | 
					                <p class="text-grey note">{{.i18n.Tr "org.teams.admin_access_helper"}}</p>
 | 
				
			||||||
            </div>
 | 
					            </div>
 | 
				
			||||||
            <hr>
 | 
					            <hr>
 | 
				
			||||||
 | 
					            {{end}}
 | 
				
			||||||
            <div class="field">
 | 
					            <div class="field">
 | 
				
			||||||
                <label></label>
 | 
					                <label></label>
 | 
				
			||||||
                <button class="btn btn-large btn-blue btn-radius">{{.i18n.Tr "org.create_new_team"}}</button>
 | 
					                {{if .PageIsOrgTeamsNew}}
 | 
				
			||||||
                <a class="btn btn-small btn-gray btn-radius" id="repo-create-cancel" href="{{.OrgLink}}/teams"><strong>{{.i18n.Tr "cancel"}}</strong></a>
 | 
					                    <button class="btn btn-large btn-blue btn-radius">{{.i18n.Tr "org.create_new_team"}}</button>
 | 
				
			||||||
 | 
					                    <a class="btn btn-small btn-gray btn-radius" id="repo-create-cancel" href="{{.OrgLink}}/teams"><strong>{{.i18n.Tr "cancel"}}</strong></a>
 | 
				
			||||||
 | 
					                {{else}}
 | 
				
			||||||
 | 
					                    <button class="btn btn-large btn-green btn-radius">{{.i18n.Tr "org.teams.update_settings"}}</button>
 | 
				
			||||||
 | 
					                    {{if not (eq .Team.LowerName "owners")}}
 | 
				
			||||||
 | 
					                         
 | 
				
			||||||
 | 
					                    <button class="btn btn-large btn-red btn-radius" id="org-team-delete">{{.i18n.Tr "org.teams.delete_team"}}</button>
 | 
				
			||||||
 | 
					                    {{end}}
 | 
				
			||||||
 | 
					                {{end}}
 | 
				
			||||||
            </div>
 | 
					            </div>
 | 
				
			||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
    </form>
 | 
					    </form>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,9 +1,9 @@
 | 
				
			|||||||
<div class="grid-1-3 panel panel-radius left" id="org-team-card">
 | 
					<div class="grid-1-3 panel panel-radius left" id="org-team-card">
 | 
				
			||||||
    <div class="panel-header">
 | 
					    <div class="panel-header">
 | 
				
			||||||
		{{if .Team.IsMember $.SignedUser.Id}}
 | 
							{{if .Team.IsMember $.SignedUser.Id}}
 | 
				
			||||||
        <a class="btn btn-small btn-red btn-header btn-radius right" href="{{.OrgLink}}/teams/{{.Team.LowerName}}/action/leave?page=team">{{$.i18n.Tr "org.teams.leave"}}</a>
 | 
					        <a class="btn btn-small btn-red btn-header btn-radius right" href="{{.OrgLink}}/teams/{{.Team.LowerName}}/action/leave?uid={{$.SignedUser.Id}}&page=team">{{$.i18n.Tr "org.teams.leave"}}</a>
 | 
				
			||||||
        {{else}}
 | 
					        {{else if .IsOrganizationOwner}}
 | 
				
			||||||
        <a class="btn btn-small btn-blue btn-header btn-radius right" href="{{.OrgLink}}/teams/{{.Team.LowerName}}/action/join?page=team">{{$.i18n.Tr "org.teams.join"}}</a>
 | 
					        <a class="btn btn-small btn-blue btn-header btn-radius right" href="{{.OrgLink}}/teams/{{.Team.LowerName}}/action/join?uid={{$.SignedUser.Id}}&page=team">{{$.i18n.Tr "org.teams.join"}}</a>
 | 
				
			||||||
        {{end}}
 | 
					        {{end}}
 | 
				
			||||||
    	<strong>{{.Team.Name}}</strong>
 | 
					    	<strong>{{.Team.Name}}</strong>
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
@@ -11,16 +11,24 @@
 | 
				
			|||||||
    	<p class="desc">{{if .Team.Description}}{{.Team.Description}}{{else}}{{.i18n.Tr "org.teams.no_desc"}}{{end}}</p>
 | 
					    	<p class="desc">{{if .Team.Description}}{{.Team.Description}}{{else}}{{.i18n.Tr "org.teams.no_desc"}}{{end}}</p>
 | 
				
			||||||
    	<hr>
 | 
					    	<hr>
 | 
				
			||||||
    	<div class="team-stats">
 | 
					    	<div class="team-stats">
 | 
				
			||||||
    		<a class="text-black"><strong>{{.Team.NumMembers}}</strong> {{$.i18n.Tr "org.lower_members"}}</a> ·
 | 
					    		<a class="text-black" href="{{.OrgLink}}/teams/{{.Team.LowerName}}"><strong>{{.Team.NumMembers}}</strong> {{$.i18n.Tr "org.lower_members"}}</a> ·
 | 
				
			||||||
    		<a class="text-black"><strong>{{.Team.NumRepos}}</strong> {{$.i18n.Tr "org.lower_repositories"}}</a>
 | 
					    		<a class="text-black" href="{{.OrgLink}}/teams/{{.Team.LowerName}}/repositories"><strong>{{.Team.NumRepos}}</strong> {{$.i18n.Tr "org.lower_repositories"}}</a>
 | 
				
			||||||
    	</div>
 | 
					    	</div>
 | 
				
			||||||
    	<p class="desc">
 | 
					    	<p class="desc">
 | 
				
			||||||
    		{{if eq .Team.LowerName "owners"}}
 | 
					    		{{if eq .Team.LowerName "owners"}}
 | 
				
			||||||
    		{{.i18n.Tr "org.teams.owners_permission_desc" | Str2html}}
 | 
					    		{{.i18n.Tr "org.teams.owners_permission_desc" | Str2html}}
 | 
				
			||||||
 | 
					            {{else if (eq .Team.Authorize 1)}}
 | 
				
			||||||
 | 
					            {{.i18n.Tr "org.teams.read_permission_desc" | Str2html}}
 | 
				
			||||||
 | 
					            {{else if (eq .Team.Authorize 2)}}
 | 
				
			||||||
 | 
					            {{.i18n.Tr "org.teams.write_permission_desc" | Str2html}}
 | 
				
			||||||
 | 
					            {{else if (eq .Team.Authorize 3)}}
 | 
				
			||||||
 | 
					            {{.i18n.Tr "org.teams.admin_permission_desc" | Str2html}}
 | 
				
			||||||
    		{{end}}
 | 
					    		{{end}}
 | 
				
			||||||
      	</p>
 | 
					      	</p>
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
 | 
					    {{if .IsOrganizationOwner}}
 | 
				
			||||||
    <div class="panel-footer">
 | 
					    <div class="panel-footer">
 | 
				
			||||||
    	<a class="btn btn-medium btn-green btn-link btn-radius" href="{{.OrgLink}}/teams/{{.Team.LowerName}}/edit"><span class="octicon octicon-gear"></span> {{$.i18n.Tr "org.teams.settings"}}</a>
 | 
					    	<a class="btn btn-medium btn-green btn-link btn-radius" href="{{.OrgLink}}/teams/{{.Team.LowerName}}/edit"><span class="octicon octicon-gear"></span> {{$.i18n.Tr "org.teams.settings"}}</a>
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
 | 
					    {{end}}
 | 
				
			||||||
</div>
 | 
					</div>
 | 
				
			||||||
@@ -6,7 +6,7 @@
 | 
				
			|||||||
		{{template "ng/base/alert" .}}
 | 
							{{template "ng/base/alert" .}}
 | 
				
			||||||
	</div>
 | 
						</div>
 | 
				
			||||||
	<div class="org-toolbar clear">
 | 
						<div class="org-toolbar clear">
 | 
				
			||||||
		{{if .IsAdminTeam}}
 | 
							{{if .IsOrganizationOwner}}
 | 
				
			||||||
        <a class="btn btn-green btn-large btn-link btn-radius right" href="{{.OrgLink}}/teams/new"><i class="octicon octicon-repo-create"></i> {{.i18n.Tr "org.create_new_team"}}</a>
 | 
					        <a class="btn btn-green btn-large btn-link btn-radius right" href="{{.OrgLink}}/teams/new"><i class="octicon octicon-repo-create"></i> {{.i18n.Tr "org.create_new_team"}}</a>
 | 
				
			||||||
		{{end}}
 | 
							{{end}}
 | 
				
			||||||
	</div>
 | 
						</div>
 | 
				
			||||||
@@ -16,9 +16,9 @@
 | 
				
			|||||||
			<div class="panel panel-radius">
 | 
								<div class="panel panel-radius">
 | 
				
			||||||
				<div class="panel-header">
 | 
									<div class="panel-header">
 | 
				
			||||||
					{{if .IsMember $.SignedUser.Id}}
 | 
										{{if .IsMember $.SignedUser.Id}}
 | 
				
			||||||
                    <a class="btn btn-small btn-red btn-header btn-radius right" href="{{$.OrgLink}}/teams/{{.LowerName}}/action/leave">{{$.i18n.Tr "org.teams.leave"}}</a>
 | 
					                    <a class="btn btn-small btn-red btn-header btn-radius right" href="{{$.OrgLink}}/teams/{{.LowerName}}/action/leave?uid={{$.SignedUser.Id}}">{{$.i18n.Tr "org.teams.leave"}}</a>
 | 
				
			||||||
                    {{else}}
 | 
					                    {{else if $.IsOrganizationOwner}}
 | 
				
			||||||
                    <a class="btn btn-small btn-blue btn-header btn-radius right" href="{{$.OrgLink}}/teams/{{.LowerName}}/action/join">{{$.i18n.Tr "org.teams.join"}}</a>
 | 
					                    <a class="btn btn-small btn-blue btn-header btn-radius right" href="{{$.OrgLink}}/teams/{{.LowerName}}/action/join?uid={{$.SignedUser.Id}}">{{$.i18n.Tr "org.teams.join"}}</a>
 | 
				
			||||||
                    {{end}}
 | 
					                    {{end}}
 | 
				
			||||||
                    <a class="text-black" href="{{$.OrgLink}}/teams/{{.LowerName}}"><strong>{{.Name}}</strong></a>
 | 
					                    <a class="text-black" href="{{$.OrgLink}}/teams/{{.LowerName}}"><strong>{{.Name}}</strong></a>
 | 
				
			||||||
				</div>
 | 
									</div>
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user