Files

260 lines
8.8 KiB
Go
Raw Permalink Normal View History

2014-08-14 14:12:21 +08:00
// Copyright 2014 The Gogs Authors. All rights reserved.
// Copyright 2019 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
2014-08-14 14:12:21 +08:00
package org
import (
"errors"
"net/http"
2021-11-16 18:18:25 +00:00
"net/url"
2015-09-17 17:21:27 -04:00
"code.gitea.io/gitea/models/db"
packages_model "code.gitea.io/gitea/models/packages"
2021-12-12 23:48:20 +08:00
repo_model "code.gitea.io/gitea/models/repo"
user_model "code.gitea.io/gitea/models/user"
2021-11-10 13:13:16 +08:00
"code.gitea.io/gitea/models/webhook"
"code.gitea.io/gitea/modules/log"
2024-02-04 14:29:09 +01:00
"code.gitea.io/gitea/modules/optional"
repo_module "code.gitea.io/gitea/modules/repository"
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/modules/templates"
"code.gitea.io/gitea/modules/util"
2021-01-26 23:36:53 +08:00
"code.gitea.io/gitea/modules/web"
2023-09-06 10:49:36 +02:00
shared_user "code.gitea.io/gitea/routers/web/shared/user"
user_setting "code.gitea.io/gitea/routers/web/user/setting"
"code.gitea.io/gitea/services/context"
"code.gitea.io/gitea/services/forms"
org_service "code.gitea.io/gitea/services/org"
user_service "code.gitea.io/gitea/services/user"
2014-08-14 14:12:21 +08:00
)
const (
// tplSettingsOptions template path for render settings
tplSettingsOptions templates.TplName = "org/settings/options"
// tplSettingsHooks template path for render hook settings
tplSettingsHooks templates.TplName = "org/settings/hooks"
2020-04-01 00:14:46 -04:00
// tplSettingsLabels template path for render labels settings
tplSettingsLabels templates.TplName = "org/settings/labels"
2014-08-14 14:12:21 +08:00
)
// Settings render the main settings page
2016-03-11 11:56:52 -05:00
func Settings(ctx *context.Context) {
2014-08-14 14:12:21 +08:00
ctx.Data["Title"] = ctx.Tr("org.settings")
ctx.Data["PageIsOrgSettings"] = true
2014-08-14 14:12:21 +08:00
ctx.Data["PageIsSettingsOptions"] = true
2019-07-23 20:50:39 +02:00
ctx.Data["CurrentVisibility"] = ctx.Org.Organization.Visibility
ctx.Data["RepoAdminChangeTeamAccess"] = ctx.Org.Organization.RepoAdminChangeTeamAccess
2023-09-06 10:49:36 +02:00
ctx.Data["ContextUser"] = ctx.ContextUser
2025-04-11 03:12:55 +08:00
if _, err := shared_user.RenderUserOrgHeader(ctx); err != nil {
ctx.ServerError("RenderUserOrgHeader", err)
2023-09-06 10:49:36 +02:00
return
}
ctx.HTML(http.StatusOK, tplSettingsOptions)
2014-08-14 14:12:21 +08:00
}
// SettingsPost response for settings change submitted
2021-01-26 23:36:53 +08:00
func SettingsPost(ctx *context.Context) {
form := web.GetForm(ctx).(*forms.UpdateOrgSettingForm)
2014-08-14 14:12:21 +08:00
ctx.Data["Title"] = ctx.Tr("org.settings")
ctx.Data["PageIsOrgSettings"] = true
2014-08-14 14:12:21 +08:00
ctx.Data["PageIsSettingsOptions"] = true
2019-07-23 20:50:39 +02:00
ctx.Data["CurrentVisibility"] = ctx.Org.Organization.Visibility
2014-08-14 14:12:21 +08:00
if ctx.HasError() {
ctx.HTML(http.StatusOK, tplSettingsOptions)
2014-08-14 14:12:21 +08:00
return
}
org := ctx.Org.Organization
if err := org_service.UpdateOrgEmailAddress(ctx, org, form.Email); err != nil {
if errors.Is(err, util.ErrInvalidArgument) {
2024-02-04 14:29:09 +01:00
ctx.Data["Err_Email"] = true
2026-02-27 20:38:44 +08:00
ctx.RenderWithErrDeprecated(ctx.Tr("form.email_invalid"), tplSettingsOptions, &form)
2024-02-04 14:29:09 +01:00
return
}
ctx.ServerError("UpdateOrgEmailAddress", err)
return
2024-02-04 14:29:09 +01:00
}
2014-08-14 14:12:21 +08:00
2024-02-04 14:29:09 +01:00
opts := &user_service.UpdateOptions{
FullName: optional.FromPtr(form.FullName),
Description: optional.FromPtr(form.Description),
Website: optional.FromPtr(form.Website),
Location: optional.FromPtr(form.Location),
RepoAdminChangeTeamAccess: optional.FromPtr(form.RepoAdminChangeTeamAccess),
2024-02-04 14:29:09 +01:00
}
2022-03-22 08:03:22 +01:00
if ctx.Doer.IsAdmin {
opts.MaxRepoCreation = optional.FromPtr(form.MaxRepoCreation)
}
2024-02-04 14:29:09 +01:00
if err := user_service.UpdateUser(ctx, org.AsUser(), opts); err != nil {
2018-01-10 22:34:17 +01:00
ctx.ServerError("UpdateUser", err)
2014-08-14 14:12:21 +08:00
return
}
2014-08-14 14:12:21 +08:00
log.Trace("Organization setting updated: %s", org.Name)
ctx.Flash.Success(ctx.Tr("org.settings.update_setting_success"))
2015-11-24 19:28:24 -05:00
ctx.Redirect(ctx.Org.OrgLink + "/settings")
2014-08-14 14:12:21 +08:00
}
// SettingsAvatar response for change avatar on settings page
2021-01-26 23:36:53 +08:00
func SettingsAvatar(ctx *context.Context) {
form := web.GetForm(ctx).(*forms.AvatarForm)
form.Source = forms.AvatarLocal
if err := user_setting.UpdateAvatarSetting(ctx, form, ctx.Org.Organization.AsUser()); err != nil {
2015-09-06 17:12:02 -04:00
ctx.Flash.Error(err.Error())
} else {
ctx.Flash.Success(ctx.Tr("org.settings.update_avatar_success"))
}
2016-03-06 17:36:30 +01:00
ctx.Redirect(ctx.Org.OrgLink + "/settings")
}
// SettingsDeleteAvatar response for delete avatar on settings page
2016-03-11 11:56:52 -05:00
func SettingsDeleteAvatar(ctx *context.Context) {
if err := user_service.DeleteAvatar(ctx, ctx.Org.Organization.AsUser()); err != nil {
2016-03-06 17:36:30 +01:00
ctx.Flash.Error(err.Error())
}
ctx.JSONRedirect(ctx.Org.OrgLink + "/settings")
2015-09-06 17:12:02 -04:00
}
// SettingsDeleteOrgPost response for deleting an organization
func SettingsDeleteOrgPost(ctx *context.Context) {
if ctx.Org.Organization.Name != ctx.FormString("org_name") {
ctx.JSONError(ctx.Tr("form.enterred_invalid_org_name"))
2014-08-14 14:12:21 +08:00
return
}
if err := org_service.DeleteOrganization(ctx, ctx.Org.Organization, false /* no purge */); err != nil {
if repo_model.IsErrUserOwnRepos(err) {
ctx.JSONError(ctx.Tr("form.org_still_own_repo"))
} else if packages_model.IsErrUserOwnPackages(err) {
ctx.JSONError(ctx.Tr("form.org_still_own_packages"))
} else {
log.Error("DeleteOrganization: %v", err)
ctx.JSONError(util.Iif(ctx.Doer.IsAdmin, err.Error(), string(ctx.Tr("org.settings.delete_failed"))))
}
2023-09-06 10:49:36 +02:00
return
}
ctx.Flash.Success(ctx.Tr("org.settings.delete_successful", ctx.Org.Organization.Name))
ctx.JSONRedirect(setting.AppSubURL + "/")
2014-08-14 14:12:21 +08:00
}
2014-09-04 07:17:00 -04:00
// Webhooks render webhook list page
2016-03-11 11:56:52 -05:00
func Webhooks(ctx *context.Context) {
2014-09-04 07:17:00 -04:00
ctx.Data["Title"] = ctx.Tr("org.settings")
ctx.Data["PageIsOrgSettings"] = true
2014-09-04 07:17:00 -04:00
ctx.Data["PageIsSettingsHooks"] = true
2019-03-18 22:33:20 -04:00
ctx.Data["BaseLink"] = ctx.Org.OrgLink + "/settings/hooks"
ctx.Data["BaseLinkNew"] = ctx.Org.OrgLink + "/settings/hooks"
2015-08-26 21:45:51 +08:00
ctx.Data["Description"] = ctx.Tr("org.settings.hooks_desc")
2014-09-04 07:17:00 -04:00
ws, err := db.Find[webhook.Webhook](ctx, webhook.ListWebhookOptions{OwnerID: ctx.Org.Organization.ID})
2014-09-04 07:17:00 -04:00
if err != nil {
2023-03-10 15:28:32 +01:00
ctx.ServerError("ListWebhooksByOpts", err)
2014-09-04 07:17:00 -04:00
return
}
2025-04-11 03:12:55 +08:00
if _, err := shared_user.RenderUserOrgHeader(ctx); err != nil {
ctx.ServerError("RenderUserOrgHeader", err)
2023-09-06 10:49:36 +02:00
return
}
2014-09-04 07:17:00 -04:00
ctx.Data["Webhooks"] = ws
ctx.HTML(http.StatusOK, tplSettingsHooks)
2014-09-04 07:17:00 -04:00
}
2015-08-26 21:45:51 +08:00
// DeleteWebhook response for delete webhook
2016-03-11 11:56:52 -05:00
func DeleteWebhook(ctx *context.Context) {
if err := webhook.DeleteWebhookByOwnerID(ctx, ctx.Org.Organization.ID, ctx.FormInt64("id")); err != nil {
2023-03-10 15:28:32 +01:00
ctx.Flash.Error("DeleteWebhookByOwnerID: " + err.Error())
2015-08-26 21:45:51 +08:00
} else {
ctx.Flash.Success(ctx.Tr("repo.settings.webhook_deletion_success"))
}
ctx.JSONRedirect(ctx.Org.OrgLink + "/settings/hooks")
2015-08-26 21:45:51 +08:00
}
2020-04-01 00:14:46 -04:00
// Labels render organization labels page
func Labels(ctx *context.Context) {
ctx.Data["Title"] = ctx.Tr("repo.labels")
ctx.Data["PageIsOrgSettings"] = true
2020-04-01 00:14:46 -04:00
ctx.Data["PageIsOrgSettingsLabels"] = true
ctx.Data["LabelTemplateFiles"] = repo_module.LabelTemplateFiles
2023-09-06 10:49:36 +02:00
2025-04-11 03:12:55 +08:00
if _, err := shared_user.RenderUserOrgHeader(ctx); err != nil {
ctx.ServerError("RenderUserOrgHeader", err)
2023-09-06 10:49:36 +02:00
return
}
ctx.HTML(http.StatusOK, tplSettingsLabels)
2020-04-01 00:14:46 -04:00
}
// SettingsRenamePost response for renaming organization
func SettingsRenamePost(ctx *context.Context) {
form := web.GetForm(ctx).(*forms.RenameOrgForm)
if ctx.HasError() {
ctx.JSONError(ctx.GetErrMsg())
return
}
oldOrgName, newOrgName := ctx.Org.Organization.Name, form.NewOrgName
if form.OrgName != oldOrgName {
ctx.JSONError(ctx.Tr("form.enterred_invalid_org_name"))
return
}
if newOrgName == oldOrgName {
ctx.JSONError(ctx.Tr("org.settings.rename_no_change"))
return
}
if err := user_service.RenameUser(ctx, ctx.Org.Organization.AsUser(), newOrgName, ctx.Doer); err != nil {
if user_model.IsErrUserAlreadyExist(err) {
ctx.JSONError(ctx.Tr("org.form.name_been_taken", newOrgName))
} else if db.IsErrNameReserved(err) {
ctx.JSONError(ctx.Tr("org.form.name_reserved", newOrgName))
} else if db.IsErrNamePatternNotAllowed(err) {
ctx.JSONError(ctx.Tr("org.form.name_pattern_not_allowed", newOrgName))
} else {
log.Error("RenameOrganization: %v", err)
ctx.JSONError(util.Iif(ctx.Doer.IsAdmin, err.Error(), string(ctx.Tr("org.settings.rename_failed"))))
}
return
}
ctx.Flash.Success(ctx.Tr("org.settings.rename_success", oldOrgName, newOrgName))
ctx.JSONRedirect(setting.AppSubURL + "/org/" + url.PathEscape(newOrgName) + "/settings")
}
// SettingsChangeVisibilityPost response for change organization visibility
func SettingsChangeVisibilityPost(ctx *context.Context) {
visibility, ok := structs.VisibilityModes[ctx.FormString("visibility")]
if !ok {
ctx.Flash.Error(ctx.Tr("invalid_data", visibility))
ctx.JSONRedirect(setting.AppSubURL + "/org/" + url.PathEscape(ctx.Org.Organization.Name) + "/settings")
return
}
if ctx.Org.Organization.Visibility == visibility {
ctx.Flash.Info(ctx.Tr("nothing_has_been_changed"))
ctx.JSONRedirect(setting.AppSubURL + "/org/" + url.PathEscape(ctx.Org.Organization.Name) + "/settings")
return
}
if err := org_service.ChangeOrganizationVisibility(ctx, ctx.Org.Organization, visibility); err != nil {
log.Error("ChangeOrganizationVisibility: %v", err)
ctx.JSONError(ctx.Tr("error.occurred"))
return
}
ctx.Flash.Success(ctx.Tr("org.settings.change_visibility_success", ctx.Org.Organization.Name))
ctx.JSONRedirect(setting.AppSubURL + "/org/" + url.PathEscape(ctx.Org.Organization.Name) + "/settings")
}