2014-06-30 00:30:41 +04:00
// Copyright 2014 The Gogs Authors. All rights reserved.
2019-11-06 12:37:14 +03:00
// Copyright 2019 The Gitea Authors. All rights reserved.
2014-06-30 00:30:41 +04:00
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
2014-06-27 17:33:49 +04:00
package org
import (
2019-06-12 22:41:28 +03:00
"net/http"
2014-08-26 14:11:15 +04:00
"path"
2017-11-26 11:01:48 +03:00
"strings"
2014-08-26 14:11:15 +04:00
2016-11-10 19:24:48 +03:00
"code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/auth"
"code.gitea.io/gitea/modules/base"
"code.gitea.io/gitea/modules/context"
"code.gitea.io/gitea/modules/log"
2017-12-07 10:00:09 +03:00
"code.gitea.io/gitea/routers/utils"
2019-08-23 19:40:30 +03:00
"github.com/unknwon/com"
2014-06-27 17:33:49 +04:00
)
2014-06-30 00:30:41 +04:00
const (
2016-11-18 06:03:03 +03:00
// tplTeams template path for teams list page
tplTeams base . TplName = "org/team/teams"
// tplTeamNew template path for create new team page
tplTeamNew base . TplName = "org/team/new"
// tplTeamMembers template path for showing team members page
tplTeamMembers base . TplName = "org/team/members"
// tplTeamRepositories template path for showing team repositories page
tplTeamRepositories base . TplName = "org/team/repositories"
2014-06-30 00:30:41 +04:00
)
2016-11-18 06:03:03 +03:00
// Teams render teams list page
2016-03-11 19:56:52 +03:00
func Teams ( ctx * context . Context ) {
2014-08-16 12:21:17 +04:00
org := ctx . Org . Organization
ctx . Data [ "Title" ] = org . FullName
ctx . Data [ "PageIsOrgTeams" ] = true
2014-06-30 00:30:41 +04:00
for _ , t := range org . Teams {
2014-08-16 12:21:17 +04:00
if err := t . GetMembers ( ) ; err != nil {
2018-01-11 00:34:17 +03:00
ctx . ServerError ( "GetMembers" , err )
2014-06-30 00:30:41 +04:00
return
}
}
ctx . Data [ "Teams" ] = org . Teams
2016-11-18 06:03:03 +03:00
ctx . HTML ( 200 , tplTeams )
2014-06-27 17:33:49 +04:00
}
2016-11-18 06:03:03 +03:00
// TeamsAction response for join, leave, remove, add operations to team
2016-03-11 19:56:52 +03:00
func TeamsAction ( ctx * context . Context ) {
2014-08-24 17:09:05 +04:00
uid := com . StrTo ( ctx . Query ( "uid" ) ) . MustInt64 ( )
if uid == 0 {
ctx . Redirect ( ctx . Org . OrgLink + "/teams" )
return
}
page := ctx . Query ( "page" )
2014-08-16 12:21:17 +04:00
var err error
switch ctx . Params ( ":action" ) {
case "join" :
2014-08-24 17:09:05 +04:00
if ! ctx . Org . IsOwner {
ctx . Error ( 404 )
return
}
2016-07-23 20:08:22 +03:00
err = ctx . Org . Team . AddMember ( ctx . User . ID )
2014-08-16 12:21:17 +04:00
case "leave" :
2016-07-23 20:08:22 +03:00
err = ctx . Org . Team . RemoveMember ( ctx . User . ID )
2014-08-24 17:09:05 +04:00
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
}
2017-12-07 10:00:09 +03:00
uname := utils . RemoveUsernameParameterSuffix ( strings . ToLower ( ctx . Query ( "uname" ) ) )
2014-08-24 17:09:05 +04:00
var u * models . User
u , err = models . GetUserByName ( uname )
if err != nil {
2015-08-05 06:14:17 +03:00
if models . IsErrUserNotExist ( err ) {
2014-08-24 17:09:05 +04:00
ctx . Flash . Error ( ctx . Tr ( "form.user_not_exist" ) )
ctx . Redirect ( ctx . Org . OrgLink + "/teams/" + ctx . Org . Team . LowerName )
} else {
2018-01-11 00:34:17 +03:00
ctx . ServerError ( " GetUserByName" , err )
2014-08-24 17:09:05 +04:00
}
return
}
2017-05-26 16:12:02 +03:00
if u . IsOrganization ( ) {
ctx . Flash . Error ( ctx . Tr ( "form.cannot_add_org_to_team" ) )
ctx . Redirect ( ctx . Org . OrgLink + "/teams/" + ctx . Org . Team . LowerName )
return
}
2018-08-19 21:49:19 +03:00
if ctx . Org . Team . IsMember ( u . ID ) {
ctx . Flash . Error ( ctx . Tr ( "org.teams.add_duplicate_users" ) )
} else {
err = ctx . Org . Team . AddMember ( u . ID )
}
2014-08-24 17:09:05 +04:00
page = "team"
2014-07-03 00:42:16 +04:00
}
2014-08-16 12:21:17 +04:00
if err != nil {
2015-03-18 04:51:39 +03:00
if models . IsErrLastOrgOwner ( err ) {
2014-08-24 17:09:05 +04:00
ctx . Flash . Error ( ctx . Tr ( "form.last_org_owner" ) )
} else {
2019-04-02 10:48:31 +03:00
log . Error ( "Action(%s): %v" , ctx . Params ( ":action" ) , err )
2014-08-24 17:09:05 +04:00
ctx . JSON ( 200 , map [ string ] interface { } {
"ok" : false ,
"err" : err . Error ( ) ,
} )
return
}
}
switch page {
case "team" :
ctx . Redirect ( ctx . Org . OrgLink + "/teams/" + ctx . Org . Team . LowerName )
2017-03-09 14:18:49 +03:00
case "home" :
ctx . Redirect ( ctx . Org . Organization . HomeLink ( ) )
2014-08-24 17:09:05 +04:00
default :
ctx . Redirect ( ctx . Org . OrgLink + "/teams" )
2014-07-03 00:42:16 +04:00
}
2014-08-16 12:21:17 +04:00
}
2014-07-03 00:42:16 +04:00
2016-11-18 06:03:03 +03:00
// TeamsRepoAction operate team's repository
2016-03-11 19:56:52 +03:00
func TeamsRepoAction ( ctx * context . Context ) {
2014-08-26 14:11:15 +04:00
if ! ctx . Org . IsOwner {
ctx . Error ( 404 )
return
}
var err error
2019-11-16 20:36:13 +03:00
action := ctx . Params ( ":action" )
switch action {
2014-08-26 14:11:15 +04:00
case "add" :
2015-11-22 09:32:09 +03:00
repoName := path . Base ( ctx . Query ( "repo_name" ) )
2014-08-26 14:11:15 +04:00
var repo * models . Repository
2016-07-23 20:08:22 +03:00
repo , err = models . GetRepositoryByName ( ctx . Org . Organization . ID , repoName )
2014-08-26 14:11:15 +04:00
if err != nil {
2015-03-16 11:04:27 +03:00
if models . IsErrRepoNotExist ( err ) {
2014-10-10 13:06:12 +04:00
ctx . Flash . Error ( ctx . Tr ( "org.teams.add_nonexistent_repo" ) )
ctx . Redirect ( ctx . Org . OrgLink + "/teams/" + ctx . Org . Team . LowerName + "/repositories" )
return
}
2018-01-11 00:34:17 +03:00
ctx . ServerError ( "GetRepositoryByName" , err )
2014-08-26 14:11:15 +04:00
return
}
err = ctx . Org . Team . AddRepository ( repo )
case "remove" :
err = ctx . Org . Team . RemoveRepository ( com . StrTo ( ctx . Query ( "repoid" ) ) . MustInt64 ( ) )
2019-11-09 03:39:37 +03:00
case "addall" :
err = ctx . Org . Team . AddAllRepositories ( )
case "removeall" :
err = ctx . Org . Team . RemoveAllRepositories ( )
2014-08-26 14:11:15 +04:00
}
if err != nil {
2019-04-02 10:48:31 +03:00
log . Error ( "Action(%s): '%s' %v" , ctx . Params ( ":action" ) , ctx . Org . Team . Name , err )
2018-01-11 00:34:17 +03:00
ctx . ServerError ( "TeamsRepoAction" , err )
2014-08-26 14:11:15 +04:00
return
}
2019-11-09 03:39:37 +03:00
2019-11-16 20:36:13 +03:00
if action == "addall" || action == "removeall" {
ctx . JSON ( 200 , map [ string ] interface { } {
"redirect" : ctx . Org . OrgLink + "/teams/" + ctx . Org . Team . LowerName + "/repositories" ,
} )
return
}
2014-08-26 14:11:15 +04:00
ctx . Redirect ( ctx . Org . OrgLink + "/teams/" + ctx . Org . Team . LowerName + "/repositories" )
}
2016-11-18 06:03:03 +03:00
// NewTeam render create new team page
2016-03-11 19:56:52 +03:00
func NewTeam ( ctx * context . Context ) {
2014-08-16 12:21:17 +04:00
ctx . Data [ "Title" ] = ctx . Org . Organization . FullName
ctx . Data [ "PageIsOrgTeams" ] = true
ctx . Data [ "PageIsOrgTeamsNew" ] = true
ctx . Data [ "Team" ] = & models . Team { }
2017-05-18 17:54:24 +03:00
ctx . Data [ "Units" ] = models . Units
2016-11-18 06:03:03 +03:00
ctx . HTML ( 200 , tplTeamNew )
2014-07-03 00:42:16 +04:00
}
2016-11-18 06:03:03 +03:00
// NewTeamPost response for create new team
2016-03-11 19:56:52 +03:00
func NewTeamPost ( ctx * context . Context , form auth . CreateTeamForm ) {
2014-08-16 12:21:17 +04:00
ctx . Data [ "Title" ] = ctx . Org . Organization . FullName
ctx . Data [ "PageIsOrgTeams" ] = true
ctx . Data [ "PageIsOrgTeamsNew" ] = true
2017-07-17 05:04:43 +03:00
ctx . Data [ "Units" ] = models . Units
2019-11-06 12:37:14 +03:00
var includesAllRepositories = ( form . RepoAccess == "all" )
2014-07-03 00:42:16 +04:00
t := & models . Team {
2019-11-06 12:37:14 +03:00
OrgID : ctx . Org . Organization . ID ,
Name : form . TeamName ,
Description : form . Description ,
Authorize : models . ParseAccessMode ( form . Permission ) ,
IncludesAllRepositories : includesAllRepositories ,
2019-11-20 14:27:49 +03:00
CanCreateOrgRepo : form . CanCreateOrgRepo ,
2014-07-03 00:42:16 +04:00
}
2018-08-21 20:02:32 +03:00
if t . Authorize < models . AccessModeOwner {
2018-06-21 19:00:13 +03:00
var units = make ( [ ] * models . TeamUnit , 0 , len ( form . Units ) )
for _ , tp := range form . Units {
units = append ( units , & models . TeamUnit {
OrgID : ctx . Org . Organization . ID ,
Type : tp ,
} )
}
t . Units = units
2017-07-17 05:04:43 +03:00
}
2016-01-30 01:06:14 +03:00
ctx . Data [ "Team" ] = t
if ctx . HasError ( ) {
2016-11-18 06:03:03 +03:00
ctx . HTML ( 200 , tplTeamNew )
2016-01-30 01:06:14 +03:00
return
}
2017-07-17 05:04:43 +03:00
if t . Authorize < models . AccessModeAdmin && len ( form . Units ) == 0 {
ctx . RenderWithErr ( ctx . Tr ( "form.team_no_units_error" ) , tplTeamNew , & form )
return
}
2014-08-16 12:21:17 +04:00
if err := models . NewTeam ( t ) ; err != nil {
2016-01-30 01:06:14 +03:00
ctx . Data [ "Err_TeamName" ] = true
switch {
case models . IsErrTeamAlreadyExist ( err ) :
2016-11-18 06:03:03 +03:00
ctx . RenderWithErr ( ctx . Tr ( "form.team_name_been_taken" ) , tplTeamNew , & form )
2014-08-16 12:21:17 +04:00
default :
2018-01-11 00:34:17 +03:00
ctx . ServerError ( "NewTeam" , err )
2014-07-03 00:42:16 +04:00
}
return
}
2016-01-30 01:06:14 +03:00
log . Trace ( "Team created: %s/%s" , ctx . Org . Organization . Name , t . Name )
2014-08-16 12:21:17 +04:00
ctx . Redirect ( ctx . Org . OrgLink + "/teams/" + t . LowerName )
2014-06-27 17:33:49 +04:00
}
2014-06-27 18:04:04 +04:00
2016-11-18 06:03:03 +03:00
// TeamMembers render team members page
2016-03-11 19:56:52 +03:00
func TeamMembers ( ctx * context . Context ) {
2014-08-24 17:09:05 +04:00
ctx . Data [ "Title" ] = ctx . Org . Team . Name
ctx . Data [ "PageIsOrgTeams" ] = true
2018-12-09 09:42:11 +03:00
ctx . Data [ "PageIsOrgTeamMembers" ] = true
2014-08-24 17:09:05 +04:00
if err := ctx . Org . Team . GetMembers ( ) ; err != nil {
2018-01-11 00:34:17 +03:00
ctx . ServerError ( "GetMembers" , err )
2014-08-24 17:09:05 +04:00
return
}
2016-11-18 06:03:03 +03:00
ctx . HTML ( 200 , tplTeamMembers )
2014-08-24 17:09:05 +04:00
}
2016-11-18 06:03:03 +03:00
// TeamRepositories show the repositories of team
2016-03-11 19:56:52 +03:00
func TeamRepositories ( ctx * context . Context ) {
2014-08-26 14:11:15 +04:00
ctx . Data [ "Title" ] = ctx . Org . Team . Name
ctx . Data [ "PageIsOrgTeams" ] = true
2018-12-09 09:42:11 +03:00
ctx . Data [ "PageIsOrgTeamRepos" ] = true
2014-08-26 14:11:15 +04:00
if err := ctx . Org . Team . GetRepositories ( ) ; err != nil {
2018-01-11 00:34:17 +03:00
ctx . ServerError ( "GetRepositories" , err )
2014-08-26 14:11:15 +04:00
return
}
2016-11-18 06:03:03 +03:00
ctx . HTML ( 200 , tplTeamRepositories )
2014-08-26 14:11:15 +04:00
}
2016-11-18 06:03:03 +03:00
// EditTeam render team edit page
2016-03-11 19:56:52 +03:00
func EditTeam ( ctx * context . Context ) {
2014-08-24 17:09:05 +04:00
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
2017-05-18 17:54:24 +03:00
ctx . Data [ "Units" ] = models . Units
2016-11-18 06:03:03 +03:00
ctx . HTML ( 200 , tplTeamNew )
2014-06-27 18:04:04 +04:00
}
2014-07-07 14:13:42 +04:00
2016-11-18 06:03:03 +03:00
// EditTeamPost response for modify team information
2016-03-11 19:56:52 +03:00
func EditTeamPost ( ctx * context . Context , form auth . CreateTeamForm ) {
2014-08-24 17:09:05 +04:00
t := ctx . Org . Team
ctx . Data [ "Title" ] = ctx . Org . Organization . FullName
2014-08-23 16:24:02 +04:00
ctx . Data [ "PageIsOrgTeams" ] = true
2016-01-30 01:06:14 +03:00
ctx . Data [ "Team" ] = t
2017-07-17 05:04:43 +03:00
ctx . Data [ "Units" ] = models . Units
2014-08-24 17:09:05 +04:00
isAuthChanged := false
2019-11-06 12:37:14 +03:00
isIncludeAllChanged := false
var includesAllRepositories = ( form . RepoAccess == "all" )
2014-08-24 17:09:05 +04:00
if ! t . IsOwnerTeam ( ) {
// Validate permission level.
2017-07-17 05:04:43 +03:00
auth := models . ParseAccessMode ( form . Permission )
2014-08-24 17:09:05 +04:00
t . Name = form . TeamName
if t . Authorize != auth {
isAuthChanged = true
t . Authorize = auth
}
2019-11-06 12:37:14 +03:00
if t . IncludesAllRepositories != includesAllRepositories {
isIncludeAllChanged = true
t . IncludesAllRepositories = includesAllRepositories
}
2014-08-24 17:09:05 +04:00
}
t . Description = form . Description
2018-08-21 20:02:32 +03:00
if t . Authorize < models . AccessModeOwner {
2018-06-21 19:00:13 +03:00
var units = make ( [ ] models . TeamUnit , 0 , len ( form . Units ) )
for _ , tp := range form . Units {
units = append ( units , models . TeamUnit {
OrgID : t . OrgID ,
TeamID : t . ID ,
Type : tp ,
} )
}
2019-06-12 22:41:28 +03:00
err := models . UpdateTeamUnits ( t , units )
if err != nil {
ctx . Error ( http . StatusInternalServerError , "LoadIssue" , err . Error ( ) )
return
}
2017-07-17 05:04:43 +03:00
}
2019-11-20 14:27:49 +03:00
t . CanCreateOrgRepo = form . CanCreateOrgRepo
2017-07-17 05:04:43 +03:00
if ctx . HasError ( ) {
ctx . HTML ( 200 , tplTeamNew )
return
}
if t . Authorize < models . AccessModeAdmin && len ( form . Units ) == 0 {
ctx . RenderWithErr ( ctx . Tr ( "form.team_no_units_error" ) , tplTeamNew , & form )
return
}
2019-11-06 12:37:14 +03:00
if err := models . UpdateTeam ( t , isAuthChanged , isIncludeAllChanged ) ; err != nil {
2016-01-30 01:06:14 +03:00
ctx . Data [ "Err_TeamName" ] = true
switch {
case models . IsErrTeamAlreadyExist ( err ) :
2016-11-18 06:03:03 +03:00
ctx . RenderWithErr ( ctx . Tr ( "form.team_name_been_taken" ) , tplTeamNew , & form )
2016-01-30 01:06:14 +03:00
default :
2018-01-11 00:34:17 +03:00
ctx . ServerError ( "UpdateTeam" , err )
2014-08-24 17:09:05 +04:00
}
return
}
ctx . Redirect ( ctx . Org . OrgLink + "/teams/" + t . LowerName )
}
2016-11-18 06:03:03 +03:00
// DeleteTeam response for the delete team request
2016-03-11 19:56:52 +03:00
func DeleteTeam ( ctx * context . Context ) {
2014-08-24 17:09:05 +04:00
if err := models . DeleteTeam ( ctx . Org . Team ) ; err != nil {
2015-11-22 09:32:09 +03:00
ctx . Flash . Error ( "DeleteTeam: " + err . Error ( ) )
} else {
ctx . Flash . Success ( ctx . Tr ( "org.teams.delete_team_success" ) )
2014-08-24 17:09:05 +04:00
}
2015-11-22 09:32:09 +03:00
ctx . JSON ( 200 , map [ string ] interface { } {
"redirect" : ctx . Org . OrgLink + "/teams" ,
} )
2014-07-07 14:13:42 +04:00
}