Skip to content

Commit aab7cb6

Browse files
authored
Move some files under repo/setting (#25585)
There are too many files under `routers/web/repo` and the file `routers/web/repo/setting.go` is too big. This PR move all setting related routers' body functions under `routers/web/repo/setting` and also split `routers/web/repo/setting.go`
1 parent cea9401 commit aab7cb6

12 files changed

+560
-478
lines changed

routers/web/repo/setting/avatar.go

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
// Copyright 2023 The Gitea Authors. All rights reserved.
2+
// SPDX-License-Identifier: MIT
3+
4+
package setting
5+
6+
import (
7+
"errors"
8+
"fmt"
9+
"io"
10+
11+
"code.gitea.io/gitea/modules/context"
12+
"code.gitea.io/gitea/modules/log"
13+
"code.gitea.io/gitea/modules/setting"
14+
"code.gitea.io/gitea/modules/typesniffer"
15+
"code.gitea.io/gitea/modules/web"
16+
"code.gitea.io/gitea/services/forms"
17+
repo_service "code.gitea.io/gitea/services/repository"
18+
)
19+
20+
// UpdateAvatarSetting update repo's avatar
21+
func UpdateAvatarSetting(ctx *context.Context, form forms.AvatarForm) error {
22+
ctxRepo := ctx.Repo.Repository
23+
24+
if form.Avatar == nil {
25+
// No avatar is uploaded and we not removing it here.
26+
// No random avatar generated here.
27+
// Just exit, no action.
28+
if ctxRepo.CustomAvatarRelativePath() == "" {
29+
log.Trace("No avatar was uploaded for repo: %d. Default icon will appear instead.", ctxRepo.ID)
30+
}
31+
return nil
32+
}
33+
34+
r, err := form.Avatar.Open()
35+
if err != nil {
36+
return fmt.Errorf("Avatar.Open: %w", err)
37+
}
38+
defer r.Close()
39+
40+
if form.Avatar.Size > setting.Avatar.MaxFileSize {
41+
return errors.New(ctx.Tr("settings.uploaded_avatar_is_too_big"))
42+
}
43+
44+
data, err := io.ReadAll(r)
45+
if err != nil {
46+
return fmt.Errorf("io.ReadAll: %w", err)
47+
}
48+
st := typesniffer.DetectContentType(data)
49+
if !(st.IsImage() && !st.IsSvgImage()) {
50+
return errors.New(ctx.Tr("settings.uploaded_avatar_not_a_image"))
51+
}
52+
if err = repo_service.UploadAvatar(ctx, ctxRepo, data); err != nil {
53+
return fmt.Errorf("UploadAvatar: %w", err)
54+
}
55+
return nil
56+
}
57+
58+
// SettingsAvatar save new POSTed repository avatar
59+
func SettingsAvatar(ctx *context.Context) {
60+
form := web.GetForm(ctx).(*forms.AvatarForm)
61+
form.Source = forms.AvatarLocal
62+
if err := UpdateAvatarSetting(ctx, *form); err != nil {
63+
ctx.Flash.Error(err.Error())
64+
} else {
65+
ctx.Flash.Success(ctx.Tr("repo.settings.update_avatar_success"))
66+
}
67+
ctx.Redirect(ctx.Repo.RepoLink + "/settings")
68+
}
69+
70+
// SettingsDeleteAvatar delete repository avatar
71+
func SettingsDeleteAvatar(ctx *context.Context) {
72+
if err := repo_service.DeleteAvatar(ctx, ctx.Repo.Repository); err != nil {
73+
ctx.Flash.Error(fmt.Sprintf("DeleteAvatar: %v", err))
74+
}
75+
ctx.Redirect(ctx.Repo.RepoLink + "/settings")
76+
}
Lines changed: 210 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,210 @@
1+
// Copyright 2023 The Gitea Authors. All rights reserved.
2+
// SPDX-License-Identifier: MIT
3+
4+
package setting
5+
6+
import (
7+
"net/http"
8+
"strings"
9+
10+
"code.gitea.io/gitea/models"
11+
"code.gitea.io/gitea/models/db"
12+
"code.gitea.io/gitea/models/organization"
13+
"code.gitea.io/gitea/models/perm"
14+
repo_model "code.gitea.io/gitea/models/repo"
15+
unit_model "code.gitea.io/gitea/models/unit"
16+
user_model "code.gitea.io/gitea/models/user"
17+
"code.gitea.io/gitea/modules/context"
18+
"code.gitea.io/gitea/modules/log"
19+
repo_module "code.gitea.io/gitea/modules/repository"
20+
"code.gitea.io/gitea/modules/setting"
21+
"code.gitea.io/gitea/routers/utils"
22+
"code.gitea.io/gitea/services/mailer"
23+
org_service "code.gitea.io/gitea/services/org"
24+
)
25+
26+
// Collaboration render a repository's collaboration page
27+
func Collaboration(ctx *context.Context) {
28+
ctx.Data["Title"] = ctx.Tr("repo.settings.collaboration")
29+
ctx.Data["PageIsSettingsCollaboration"] = true
30+
31+
users, err := repo_model.GetCollaborators(ctx, ctx.Repo.Repository.ID, db.ListOptions{})
32+
if err != nil {
33+
ctx.ServerError("GetCollaborators", err)
34+
return
35+
}
36+
ctx.Data["Collaborators"] = users
37+
38+
teams, err := organization.GetRepoTeams(ctx, ctx.Repo.Repository)
39+
if err != nil {
40+
ctx.ServerError("GetRepoTeams", err)
41+
return
42+
}
43+
ctx.Data["Teams"] = teams
44+
ctx.Data["Repo"] = ctx.Repo.Repository
45+
ctx.Data["OrgID"] = ctx.Repo.Repository.OwnerID
46+
ctx.Data["OrgName"] = ctx.Repo.Repository.OwnerName
47+
ctx.Data["Org"] = ctx.Repo.Repository.Owner
48+
ctx.Data["Units"] = unit_model.Units
49+
50+
ctx.HTML(http.StatusOK, tplCollaboration)
51+
}
52+
53+
// CollaborationPost response for actions for a collaboration of a repository
54+
func CollaborationPost(ctx *context.Context) {
55+
name := utils.RemoveUsernameParameterSuffix(strings.ToLower(ctx.FormString("collaborator")))
56+
if len(name) == 0 || ctx.Repo.Owner.LowerName == name {
57+
ctx.Redirect(setting.AppSubURL + ctx.Req.URL.EscapedPath())
58+
return
59+
}
60+
61+
u, err := user_model.GetUserByName(ctx, name)
62+
if err != nil {
63+
if user_model.IsErrUserNotExist(err) {
64+
ctx.Flash.Error(ctx.Tr("form.user_not_exist"))
65+
ctx.Redirect(setting.AppSubURL + ctx.Req.URL.EscapedPath())
66+
} else {
67+
ctx.ServerError("GetUserByName", err)
68+
}
69+
return
70+
}
71+
72+
if !u.IsActive {
73+
ctx.Flash.Error(ctx.Tr("repo.settings.add_collaborator_inactive_user"))
74+
ctx.Redirect(setting.AppSubURL + ctx.Req.URL.EscapedPath())
75+
return
76+
}
77+
78+
// Organization is not allowed to be added as a collaborator.
79+
if u.IsOrganization() {
80+
ctx.Flash.Error(ctx.Tr("repo.settings.org_not_allowed_to_be_collaborator"))
81+
ctx.Redirect(setting.AppSubURL + ctx.Req.URL.EscapedPath())
82+
return
83+
}
84+
85+
if got, err := repo_model.IsCollaborator(ctx, ctx.Repo.Repository.ID, u.ID); err == nil && got {
86+
ctx.Flash.Error(ctx.Tr("repo.settings.add_collaborator_duplicate"))
87+
ctx.Redirect(ctx.Repo.RepoLink + "/settings/collaboration")
88+
return
89+
}
90+
91+
// find the owner team of the organization the repo belongs too and
92+
// check if the user we're trying to add is an owner.
93+
if ctx.Repo.Repository.Owner.IsOrganization() {
94+
if isOwner, err := organization.IsOrganizationOwner(ctx, ctx.Repo.Repository.Owner.ID, u.ID); err != nil {
95+
ctx.ServerError("IsOrganizationOwner", err)
96+
return
97+
} else if isOwner {
98+
ctx.Flash.Error(ctx.Tr("repo.settings.add_collaborator_owner"))
99+
ctx.Redirect(setting.AppSubURL + ctx.Req.URL.EscapedPath())
100+
return
101+
}
102+
}
103+
104+
if err = repo_module.AddCollaborator(ctx, ctx.Repo.Repository, u); err != nil {
105+
ctx.ServerError("AddCollaborator", err)
106+
return
107+
}
108+
109+
if setting.Service.EnableNotifyMail {
110+
mailer.SendCollaboratorMail(u, ctx.Doer, ctx.Repo.Repository)
111+
}
112+
113+
ctx.Flash.Success(ctx.Tr("repo.settings.add_collaborator_success"))
114+
ctx.Redirect(setting.AppSubURL + ctx.Req.URL.EscapedPath())
115+
}
116+
117+
// ChangeCollaborationAccessMode response for changing access of a collaboration
118+
func ChangeCollaborationAccessMode(ctx *context.Context) {
119+
if err := repo_model.ChangeCollaborationAccessMode(
120+
ctx,
121+
ctx.Repo.Repository,
122+
ctx.FormInt64("uid"),
123+
perm.AccessMode(ctx.FormInt("mode"))); err != nil {
124+
log.Error("ChangeCollaborationAccessMode: %v", err)
125+
}
126+
}
127+
128+
// DeleteCollaboration delete a collaboration for a repository
129+
func DeleteCollaboration(ctx *context.Context) {
130+
if err := models.DeleteCollaboration(ctx.Repo.Repository, ctx.FormInt64("id")); err != nil {
131+
ctx.Flash.Error("DeleteCollaboration: " + err.Error())
132+
} else {
133+
ctx.Flash.Success(ctx.Tr("repo.settings.remove_collaborator_success"))
134+
}
135+
136+
ctx.JSON(http.StatusOK, map[string]interface{}{
137+
"redirect": ctx.Repo.RepoLink + "/settings/collaboration",
138+
})
139+
}
140+
141+
// AddTeamPost response for adding a team to a repository
142+
func AddTeamPost(ctx *context.Context) {
143+
if !ctx.Repo.Owner.RepoAdminChangeTeamAccess && !ctx.Repo.IsOwner() {
144+
ctx.Flash.Error(ctx.Tr("repo.settings.change_team_access_not_allowed"))
145+
ctx.Redirect(ctx.Repo.RepoLink + "/settings/collaboration")
146+
return
147+
}
148+
149+
name := utils.RemoveUsernameParameterSuffix(strings.ToLower(ctx.FormString("team")))
150+
if len(name) == 0 {
151+
ctx.Redirect(ctx.Repo.RepoLink + "/settings/collaboration")
152+
return
153+
}
154+
155+
team, err := organization.OrgFromUser(ctx.Repo.Owner).GetTeam(ctx, name)
156+
if err != nil {
157+
if organization.IsErrTeamNotExist(err) {
158+
ctx.Flash.Error(ctx.Tr("form.team_not_exist"))
159+
ctx.Redirect(ctx.Repo.RepoLink + "/settings/collaboration")
160+
} else {
161+
ctx.ServerError("GetTeam", err)
162+
}
163+
return
164+
}
165+
166+
if team.OrgID != ctx.Repo.Repository.OwnerID {
167+
ctx.Flash.Error(ctx.Tr("repo.settings.team_not_in_organization"))
168+
ctx.Redirect(ctx.Repo.RepoLink + "/settings/collaboration")
169+
return
170+
}
171+
172+
if organization.HasTeamRepo(ctx, ctx.Repo.Repository.OwnerID, team.ID, ctx.Repo.Repository.ID) {
173+
ctx.Flash.Error(ctx.Tr("repo.settings.add_team_duplicate"))
174+
ctx.Redirect(ctx.Repo.RepoLink + "/settings/collaboration")
175+
return
176+
}
177+
178+
if err = org_service.TeamAddRepository(team, ctx.Repo.Repository); err != nil {
179+
ctx.ServerError("TeamAddRepository", err)
180+
return
181+
}
182+
183+
ctx.Flash.Success(ctx.Tr("repo.settings.add_team_success"))
184+
ctx.Redirect(ctx.Repo.RepoLink + "/settings/collaboration")
185+
}
186+
187+
// DeleteTeam response for deleting a team from a repository
188+
func DeleteTeam(ctx *context.Context) {
189+
if !ctx.Repo.Owner.RepoAdminChangeTeamAccess && !ctx.Repo.IsOwner() {
190+
ctx.Flash.Error(ctx.Tr("repo.settings.change_team_access_not_allowed"))
191+
ctx.Redirect(ctx.Repo.RepoLink + "/settings/collaboration")
192+
return
193+
}
194+
195+
team, err := organization.GetTeamByID(ctx, ctx.FormInt64("id"))
196+
if err != nil {
197+
ctx.ServerError("GetTeamByID", err)
198+
return
199+
}
200+
201+
if err = models.RemoveRepository(team, ctx.Repo.Repository.ID); err != nil {
202+
ctx.ServerError("team.RemoveRepositorys", err)
203+
return
204+
}
205+
206+
ctx.Flash.Success(ctx.Tr("repo.settings.remove_team_success"))
207+
ctx.JSON(http.StatusOK, map[string]interface{}{
208+
"redirect": ctx.Repo.RepoLink + "/settings/collaboration",
209+
})
210+
}
Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
// Copyright 2023 The Gitea Authors. All rights reserved.
2+
// SPDX-License-Identifier: MIT
3+
4+
package setting
5+
6+
import (
7+
"net/http"
8+
9+
asymkey_model "code.gitea.io/gitea/models/asymkey"
10+
"code.gitea.io/gitea/models/db"
11+
"code.gitea.io/gitea/modules/context"
12+
"code.gitea.io/gitea/modules/log"
13+
"code.gitea.io/gitea/modules/setting"
14+
"code.gitea.io/gitea/modules/web"
15+
asymkey_service "code.gitea.io/gitea/services/asymkey"
16+
"code.gitea.io/gitea/services/forms"
17+
)
18+
19+
// DeployKeys render the deploy keys list of a repository page
20+
func DeployKeys(ctx *context.Context) {
21+
ctx.Data["Title"] = ctx.Tr("repo.settings.deploy_keys") + " / " + ctx.Tr("secrets.secrets")
22+
ctx.Data["PageIsSettingsKeys"] = true
23+
ctx.Data["DisableSSH"] = setting.SSH.Disabled
24+
25+
keys, err := asymkey_model.ListDeployKeys(ctx, &asymkey_model.ListDeployKeysOptions{RepoID: ctx.Repo.Repository.ID})
26+
if err != nil {
27+
ctx.ServerError("ListDeployKeys", err)
28+
return
29+
}
30+
ctx.Data["Deploykeys"] = keys
31+
32+
ctx.HTML(http.StatusOK, tplDeployKeys)
33+
}
34+
35+
// DeployKeysPost response for adding a deploy key of a repository
36+
func DeployKeysPost(ctx *context.Context) {
37+
form := web.GetForm(ctx).(*forms.AddKeyForm)
38+
ctx.Data["Title"] = ctx.Tr("repo.settings.deploy_keys")
39+
ctx.Data["PageIsSettingsKeys"] = true
40+
ctx.Data["DisableSSH"] = setting.SSH.Disabled
41+
42+
keys, err := asymkey_model.ListDeployKeys(ctx, &asymkey_model.ListDeployKeysOptions{RepoID: ctx.Repo.Repository.ID})
43+
if err != nil {
44+
ctx.ServerError("ListDeployKeys", err)
45+
return
46+
}
47+
ctx.Data["Deploykeys"] = keys
48+
49+
if ctx.HasError() {
50+
ctx.HTML(http.StatusOK, tplDeployKeys)
51+
return
52+
}
53+
54+
content, err := asymkey_model.CheckPublicKeyString(form.Content)
55+
if err != nil {
56+
if db.IsErrSSHDisabled(err) {
57+
ctx.Flash.Info(ctx.Tr("settings.ssh_disabled"))
58+
} else if asymkey_model.IsErrKeyUnableVerify(err) {
59+
ctx.Flash.Info(ctx.Tr("form.unable_verify_ssh_key"))
60+
} else if err == asymkey_model.ErrKeyIsPrivate {
61+
ctx.Data["HasError"] = true
62+
ctx.Data["Err_Content"] = true
63+
ctx.Flash.Error(ctx.Tr("form.must_use_public_key"))
64+
} else {
65+
ctx.Data["HasError"] = true
66+
ctx.Data["Err_Content"] = true
67+
ctx.Flash.Error(ctx.Tr("form.invalid_ssh_key", err.Error()))
68+
}
69+
ctx.Redirect(ctx.Repo.RepoLink + "/settings/keys")
70+
return
71+
}
72+
73+
key, err := asymkey_model.AddDeployKey(ctx.Repo.Repository.ID, form.Title, content, !form.IsWritable)
74+
if err != nil {
75+
ctx.Data["HasError"] = true
76+
switch {
77+
case asymkey_model.IsErrDeployKeyAlreadyExist(err):
78+
ctx.Data["Err_Content"] = true
79+
ctx.RenderWithErr(ctx.Tr("repo.settings.key_been_used"), tplDeployKeys, &form)
80+
case asymkey_model.IsErrKeyAlreadyExist(err):
81+
ctx.Data["Err_Content"] = true
82+
ctx.RenderWithErr(ctx.Tr("settings.ssh_key_been_used"), tplDeployKeys, &form)
83+
case asymkey_model.IsErrKeyNameAlreadyUsed(err):
84+
ctx.Data["Err_Title"] = true
85+
ctx.RenderWithErr(ctx.Tr("repo.settings.key_name_used"), tplDeployKeys, &form)
86+
case asymkey_model.IsErrDeployKeyNameAlreadyUsed(err):
87+
ctx.Data["Err_Title"] = true
88+
ctx.RenderWithErr(ctx.Tr("repo.settings.key_name_used"), tplDeployKeys, &form)
89+
default:
90+
ctx.ServerError("AddDeployKey", err)
91+
}
92+
return
93+
}
94+
95+
log.Trace("Deploy key added: %d", ctx.Repo.Repository.ID)
96+
ctx.Flash.Success(ctx.Tr("repo.settings.add_key_success", key.Name))
97+
ctx.Redirect(ctx.Repo.RepoLink + "/settings/keys")
98+
}
99+
100+
// DeleteDeployKey response for deleting a deploy key
101+
func DeleteDeployKey(ctx *context.Context) {
102+
if err := asymkey_service.DeleteDeployKey(ctx.Doer, ctx.FormInt64("id")); err != nil {
103+
ctx.Flash.Error("DeleteDeployKey: " + err.Error())
104+
} else {
105+
ctx.Flash.Success(ctx.Tr("repo.settings.deploy_key_deletion_success"))
106+
}
107+
108+
ctx.JSON(http.StatusOK, map[string]interface{}{
109+
"redirect": ctx.Repo.RepoLink + "/settings/keys",
110+
})
111+
}

0 commit comments

Comments
 (0)