Skip to content

[WIP] Add team option to automatically add new organization repos #8048

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions models/org.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,10 @@ func (org *User) GetOwnerTeam() (*Team, error) {
return org.getOwnerTeam(x)
}

func (org *User) getTeamsWithAutoAddRepos(e Engine) ([]*Team, error) {
return getTeamsWithAutoAddRepos(e, org.ID)
}

func (org *User) getTeams(e Engine) error {
return e.
Where("org_id=?", org.ID).
Expand Down
30 changes: 19 additions & 11 deletions models/org_team.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,17 +21,18 @@ const ownerTeamName = "Owners"

// Team represents a organization team.
type Team struct {
ID int64 `xorm:"pk autoincr"`
OrgID int64 `xorm:"INDEX"`
LowerName string
Name string
Description string
Authorize AccessMode
Repos []*Repository `xorm:"-"`
Members []*User `xorm:"-"`
NumRepos int
NumMembers int
Units []*TeamUnit `xorm:"-"`
ID int64 `xorm:"pk autoincr"`
OrgID int64 `xorm:"INDEX"`
LowerName string
Name string
Description string
Authorize AccessMode
AutoAddNewRepo bool
Repos []*Repository `xorm:"-"`
Members []*User `xorm:"-"`
NumRepos int
NumMembers int
Units []*TeamUnit `xorm:"-"`
}

// ColorFormat provides a basic color format for a Team
Expand Down Expand Up @@ -357,6 +358,13 @@ func getTeam(e Engine, orgID int64, name string) (*Team, error) {
return t, nil
}

func getTeamsWithAutoAddRepos(e Engine, orgID int64) ([]*Team, error) {
teams := make([]*Team, 0, 5)
sess := e.Where("org_id = ?", orgID).
And("auto_add_new_repo = ?", true)
return teams, sess.Find(&teams)
}

// GetTeam returns team by given team name and organization.
func GetTeam(orgID int64, name string) (*Team, error) {
return getTeam(x, orgID, name)
Expand Down
29 changes: 27 additions & 2 deletions models/repo.go
Original file line number Diff line number Diff line change
Expand Up @@ -1318,14 +1318,27 @@ func createRepository(e *xorm.Session, doer, u *User, repo *Repository) (err err
}
u.NumRepos++

// Give access to all members in owner team.
if u.IsOrganization() {
// Give access to all members in owner team.
t, err := u.getOwnerTeam(e)
if err != nil {
return fmt.Errorf("getOwnerTeam: %v", err)
} else if err = t.addRepository(e, repo); err != nil {
return fmt.Errorf("addRepository: %v", err)
} else if err = prepareWebhooks(e, repo, HookEventRepository, &api.RepositoryPayload{
}

// Add teams that shall automatically get repo access
teams, err := u.getTeamsWithAutoAddRepos(e)
if err != nil {
return fmt.Errorf("getTeamsWithAutoAddRepos: %v", err)
}
for _, t = range teams {
if err = t.addRepository(e, repo); err != nil {
return fmt.Errorf("addRepository: %v", err)
}
}

if err = prepareWebhooks(e, repo, HookEventRepository, &api.RepositoryPayload{
Action: api.HookRepoCreated,
Repository: repo.innerAPIFormat(e, AccessModeOwner, false),
Organization: u.APIFormat(),
Expand Down Expand Up @@ -1514,12 +1527,24 @@ func TransferOwnership(doer *User, newOwnerName string, repo *Repository) error
}

if newOwner.IsOrganization() {
// Give access to all members in owner team.
t, err := newOwner.getOwnerTeam(sess)
if err != nil {
return fmt.Errorf("getOwnerTeam: %v", err)
} else if err = t.addRepository(sess, repo); err != nil {
return fmt.Errorf("add to owner team: %v", err)
}

// Add teams that shall automatically get repo access
teams, err := newOwner.getTeamsWithAutoAddRepos(sess)
if err != nil {
return fmt.Errorf("getTeamsWithAutoAddRepos: %v", err)
}
for _, t = range teams {
if err = t.addRepository(sess, repo); err != nil {
return fmt.Errorf("addRepository: %v", err)
}
}
} else if err = repo.recalculateAccesses(sess); err != nil {
// Organization called this in addRepository method.
return fmt.Errorf("recalculateAccesses: %v", err)
Expand Down
9 changes: 5 additions & 4 deletions modules/auth/org.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,10 +56,11 @@ func (f *UpdateOrgSettingForm) Validate(ctx *macaron.Context, errs binding.Error

// CreateTeamForm form for creating team
type CreateTeamForm struct {
TeamName string `binding:"Required;AlphaDashDot;MaxSize(30)"`
Description string `binding:"MaxSize(255)"`
Permission string
Units []models.UnitType
TeamName string `binding:"Required;AlphaDashDot;MaxSize(30)"`
Description string `binding:"MaxSize(255)"`
Permission string
AutoAddRepos bool
Units []models.UnitType
}

// Validate validates the fields
Expand Down
2 changes: 2 additions & 0 deletions options/locale/locale_en-US.ini
Original file line number Diff line number Diff line change
Expand Up @@ -1485,6 +1485,8 @@ members.invite_now = Invite Now

teams.join = Join
teams.leave = Leave
teams.auto_add_repo = Automatically add new repositories
teams.auto_add_repo_helper = Team will automatically get access to newly created or transferred repositories in organization.
teams.read_access = Read Access
teams.read_access_helper = Members can view and clone team repositories.
teams.write_access = Write Access
Expand Down
10 changes: 6 additions & 4 deletions routers/org/teams.go
Original file line number Diff line number Diff line change
Expand Up @@ -182,10 +182,11 @@ func NewTeamPost(ctx *context.Context, form auth.CreateTeamForm) {
ctx.Data["Units"] = models.Units

t := &models.Team{
OrgID: ctx.Org.Organization.ID,
Name: form.TeamName,
Description: form.Description,
Authorize: models.ParseAccessMode(form.Permission),
OrgID: ctx.Org.Organization.ID,
Name: form.TeamName,
Description: form.Description,
Authorize: models.ParseAccessMode(form.Permission),
AutoAddNewRepo: form.AutoAddRepos,
}

if t.Authorize < models.AccessModeOwner {
Expand Down Expand Up @@ -273,6 +274,7 @@ func EditTeamPost(ctx *context.Context, form auth.CreateTeamForm) {
auth := models.ParseAccessMode(form.Permission)

t.Name = form.TeamName
t.AutoAddNewRepo = form.AutoAddRepos
if t.Authorize != auth {
isAuthChanged = true
t.Authorize = auth
Expand Down
7 changes: 7 additions & 0 deletions templates/org/team/new.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,13 @@
<div class="grouped field">
<label>{{.i18n.Tr "org.team_permission_desc"}}</label>
<br>
<div class="field">
<div class="ui checkbox">
<input type="checkbox" name="auto_add_repos" {{if .Team.AutoAddNewRepo}}checked{{end}}>
<label>{{.i18n.Tr "org.teams.auto_add_repo"}}</label>
<span class="help">{{.i18n.Tr "org.teams.auto_add_repo_helper"}}</span>
</div>
</div>
<div class="field">
<div class="ui radio checkbox">
<input type="radio" name="permission" value="read" {{if or .PageIsOrgTeamsNew (eq .Team.Authorize 1)}}checked{{end}}>
Expand Down