mirror of
https://github.com/go-gitea/gitea.git
synced 2025-05-31 03:55:35 +00:00
Add anonymous access support for private repositories (backend) (#33257)
Follow #33127 This PR add backend logic and test for "anonymous access", it shares the same logic as "everyone access", so not too much change. By the way, split `SettingsPost` into small functions to make it easier to make frontend-related changes in the future. Next PR will add frontend support for "anonymous access"
This commit is contained in:
parent
58d0a3f4c2
commit
0d2607a303
@ -378,6 +378,7 @@ func prepareMigrationTasks() []*migration {
|
|||||||
newMigration(315, "Add Ephemeral to ActionRunner", v1_24.AddEphemeralToActionRunner),
|
newMigration(315, "Add Ephemeral to ActionRunner", v1_24.AddEphemeralToActionRunner),
|
||||||
newMigration(316, "Add description for secrets and variables", v1_24.AddDescriptionForSecretsAndVariables),
|
newMigration(316, "Add description for secrets and variables", v1_24.AddDescriptionForSecretsAndVariables),
|
||||||
newMigration(317, "Add new index for action for heatmap", v1_24.AddNewIndexForUserDashboard),
|
newMigration(317, "Add new index for action for heatmap", v1_24.AddNewIndexForUserDashboard),
|
||||||
|
newMigration(318, "Add anonymous_access_mode for repo_unit", v1_24.AddRepoUnitAnonymousAccessMode),
|
||||||
}
|
}
|
||||||
return preparedMigrations
|
return preparedMigrations
|
||||||
}
|
}
|
||||||
|
17
models/migrations/v1_24/v318.go
Normal file
17
models/migrations/v1_24/v318.go
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
// Copyright 2025 The Gitea Authors. All rights reserved.
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
package v1_24 //nolint
|
||||||
|
|
||||||
|
import (
|
||||||
|
"code.gitea.io/gitea/models/perm"
|
||||||
|
|
||||||
|
"xorm.io/xorm"
|
||||||
|
)
|
||||||
|
|
||||||
|
func AddRepoUnitAnonymousAccessMode(x *xorm.Engine) error {
|
||||||
|
type RepoUnit struct { //revive:disable-line:exported
|
||||||
|
AnonymousAccessMode perm.AccessMode `xorm:"NOT NULL DEFAULT 0"`
|
||||||
|
}
|
||||||
|
return x.Sync(&RepoUnit{})
|
||||||
|
}
|
@ -25,7 +25,8 @@ type Permission struct {
|
|||||||
units []*repo_model.RepoUnit
|
units []*repo_model.RepoUnit
|
||||||
unitsMode map[unit.Type]perm_model.AccessMode
|
unitsMode map[unit.Type]perm_model.AccessMode
|
||||||
|
|
||||||
everyoneAccessMode map[unit.Type]perm_model.AccessMode
|
everyoneAccessMode map[unit.Type]perm_model.AccessMode // the unit's minimal access mode for every signed-in user
|
||||||
|
anonymousAccessMode map[unit.Type]perm_model.AccessMode // the unit's minimal access mode for anonymous (non-signed-in) user
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsOwner returns true if current user is the owner of repository.
|
// IsOwner returns true if current user is the owner of repository.
|
||||||
@ -39,7 +40,7 @@ func (p *Permission) IsAdmin() bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// HasAnyUnitAccess returns true if the user might have at least one access mode to any unit of this repository.
|
// HasAnyUnitAccess returns true if the user might have at least one access mode to any unit of this repository.
|
||||||
// It doesn't count the "everyone access mode".
|
// It doesn't count the "public(anonymous/everyone) access mode".
|
||||||
func (p *Permission) HasAnyUnitAccess() bool {
|
func (p *Permission) HasAnyUnitAccess() bool {
|
||||||
for _, v := range p.unitsMode {
|
for _, v := range p.unitsMode {
|
||||||
if v >= perm_model.AccessModeRead {
|
if v >= perm_model.AccessModeRead {
|
||||||
@ -49,7 +50,12 @@ func (p *Permission) HasAnyUnitAccess() bool {
|
|||||||
return p.AccessMode >= perm_model.AccessModeRead
|
return p.AccessMode >= perm_model.AccessModeRead
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Permission) HasAnyUnitAccessOrEveryoneAccess() bool {
|
func (p *Permission) HasAnyUnitAccessOrPublicAccess() bool {
|
||||||
|
for _, v := range p.anonymousAccessMode {
|
||||||
|
if v >= perm_model.AccessModeRead {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
for _, v := range p.everyoneAccessMode {
|
for _, v := range p.everyoneAccessMode {
|
||||||
if v >= perm_model.AccessModeRead {
|
if v >= perm_model.AccessModeRead {
|
||||||
return true
|
return true
|
||||||
@ -73,14 +79,16 @@ func (p *Permission) GetFirstUnitRepoID() int64 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// UnitAccessMode returns current user access mode to the specify unit of the repository
|
// UnitAccessMode returns current user access mode to the specify unit of the repository
|
||||||
// It also considers "everyone access mode"
|
// It also considers "public (anonymous/everyone) access mode"
|
||||||
func (p *Permission) UnitAccessMode(unitType unit.Type) perm_model.AccessMode {
|
func (p *Permission) UnitAccessMode(unitType unit.Type) perm_model.AccessMode {
|
||||||
// if the units map contains the access mode, use it, but admin/owner mode could override it
|
// if the units map contains the access mode, use it, but admin/owner mode could override it
|
||||||
if m, ok := p.unitsMode[unitType]; ok {
|
if m, ok := p.unitsMode[unitType]; ok {
|
||||||
return util.Iif(p.AccessMode >= perm_model.AccessModeAdmin, p.AccessMode, m)
|
return util.Iif(p.AccessMode >= perm_model.AccessModeAdmin, p.AccessMode, m)
|
||||||
}
|
}
|
||||||
// if the units map does not contain the access mode, return the default access mode if the unit exists
|
// if the units map does not contain the access mode, return the default access mode if the unit exists
|
||||||
unitDefaultAccessMode := max(p.AccessMode, p.everyoneAccessMode[unitType])
|
unitDefaultAccessMode := p.AccessMode
|
||||||
|
unitDefaultAccessMode = max(unitDefaultAccessMode, p.anonymousAccessMode[unitType])
|
||||||
|
unitDefaultAccessMode = max(unitDefaultAccessMode, p.everyoneAccessMode[unitType])
|
||||||
hasUnit := slices.ContainsFunc(p.units, func(u *repo_model.RepoUnit) bool { return u.Type == unitType })
|
hasUnit := slices.ContainsFunc(p.units, func(u *repo_model.RepoUnit) bool { return u.Type == unitType })
|
||||||
return util.Iif(hasUnit, unitDefaultAccessMode, perm_model.AccessModeNone)
|
return util.Iif(hasUnit, unitDefaultAccessMode, perm_model.AccessModeNone)
|
||||||
}
|
}
|
||||||
@ -171,27 +179,38 @@ func (p *Permission) LogString() string {
|
|||||||
format += "\n\tunitsMode[%-v]: %-v"
|
format += "\n\tunitsMode[%-v]: %-v"
|
||||||
args = append(args, key.LogString(), value.LogString())
|
args = append(args, key.LogString(), value.LogString())
|
||||||
}
|
}
|
||||||
|
format += "\n\tanonymousAccessMode: %-v"
|
||||||
|
args = append(args, p.anonymousAccessMode)
|
||||||
format += "\n\teveryoneAccessMode: %-v"
|
format += "\n\teveryoneAccessMode: %-v"
|
||||||
args = append(args, p.everyoneAccessMode)
|
args = append(args, p.everyoneAccessMode)
|
||||||
format += "\n\t]>"
|
format += "\n\t]>"
|
||||||
return fmt.Sprintf(format, args...)
|
return fmt.Sprintf(format, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func applyPublicAccessPermission(unitType unit.Type, accessMode perm_model.AccessMode, modeMap *map[unit.Type]perm_model.AccessMode) {
|
||||||
|
if accessMode >= perm_model.AccessModeRead && accessMode > (*modeMap)[unitType] {
|
||||||
|
if *modeMap == nil {
|
||||||
|
*modeMap = make(map[unit.Type]perm_model.AccessMode)
|
||||||
|
}
|
||||||
|
(*modeMap)[unitType] = accessMode
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func finalProcessRepoUnitPermission(user *user_model.User, perm *Permission) {
|
func finalProcessRepoUnitPermission(user *user_model.User, perm *Permission) {
|
||||||
|
// apply public (anonymous) access permissions
|
||||||
|
for _, u := range perm.units {
|
||||||
|
applyPublicAccessPermission(u.Type, u.AnonymousAccessMode, &perm.anonymousAccessMode)
|
||||||
|
}
|
||||||
|
|
||||||
if user == nil || user.ID <= 0 {
|
if user == nil || user.ID <= 0 {
|
||||||
// for anonymous access, it could be:
|
// for anonymous access, it could be:
|
||||||
// AccessMode is None or Read, units has repo units, unitModes is nil
|
// AccessMode is None or Read, units has repo units, unitModes is nil
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// apply everyone access permissions
|
// apply public (everyone) access permissions
|
||||||
for _, u := range perm.units {
|
for _, u := range perm.units {
|
||||||
if u.EveryoneAccessMode >= perm_model.AccessModeRead && u.EveryoneAccessMode > perm.everyoneAccessMode[u.Type] {
|
applyPublicAccessPermission(u.Type, u.EveryoneAccessMode, &perm.everyoneAccessMode)
|
||||||
if perm.everyoneAccessMode == nil {
|
|
||||||
perm.everyoneAccessMode = make(map[unit.Type]perm_model.AccessMode)
|
|
||||||
}
|
|
||||||
perm.everyoneAccessMode[u.Type] = u.EveryoneAccessMode
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if perm.unitsMode == nil {
|
if perm.unitsMode == nil {
|
||||||
@ -209,6 +228,11 @@ func finalProcessRepoUnitPermission(user *user_model.User, perm *Permission) {
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
for t := range perm.anonymousAccessMode {
|
||||||
|
if shouldKeep = shouldKeep || u.Type == t; shouldKeep {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
for t := range perm.everyoneAccessMode {
|
for t := range perm.everyoneAccessMode {
|
||||||
if shouldKeep = shouldKeep || u.Type == t; shouldKeep {
|
if shouldKeep = shouldKeep || u.Type == t; shouldKeep {
|
||||||
break
|
break
|
||||||
|
@ -22,14 +22,21 @@ func TestHasAnyUnitAccess(t *testing.T) {
|
|||||||
units: []*repo_model.RepoUnit{{Type: unit.TypeWiki}},
|
units: []*repo_model.RepoUnit{{Type: unit.TypeWiki}},
|
||||||
}
|
}
|
||||||
assert.False(t, perm.HasAnyUnitAccess())
|
assert.False(t, perm.HasAnyUnitAccess())
|
||||||
assert.False(t, perm.HasAnyUnitAccessOrEveryoneAccess())
|
assert.False(t, perm.HasAnyUnitAccessOrPublicAccess())
|
||||||
|
|
||||||
perm = Permission{
|
perm = Permission{
|
||||||
units: []*repo_model.RepoUnit{{Type: unit.TypeWiki}},
|
units: []*repo_model.RepoUnit{{Type: unit.TypeWiki}},
|
||||||
everyoneAccessMode: map[unit.Type]perm_model.AccessMode{unit.TypeIssues: perm_model.AccessModeRead},
|
everyoneAccessMode: map[unit.Type]perm_model.AccessMode{unit.TypeIssues: perm_model.AccessModeRead},
|
||||||
}
|
}
|
||||||
assert.False(t, perm.HasAnyUnitAccess())
|
assert.False(t, perm.HasAnyUnitAccess())
|
||||||
assert.True(t, perm.HasAnyUnitAccessOrEveryoneAccess())
|
assert.True(t, perm.HasAnyUnitAccessOrPublicAccess())
|
||||||
|
|
||||||
|
perm = Permission{
|
||||||
|
units: []*repo_model.RepoUnit{{Type: unit.TypeWiki}},
|
||||||
|
anonymousAccessMode: map[unit.Type]perm_model.AccessMode{unit.TypeIssues: perm_model.AccessModeRead},
|
||||||
|
}
|
||||||
|
assert.False(t, perm.HasAnyUnitAccess())
|
||||||
|
assert.True(t, perm.HasAnyUnitAccessOrPublicAccess())
|
||||||
|
|
||||||
perm = Permission{
|
perm = Permission{
|
||||||
AccessMode: perm_model.AccessModeRead,
|
AccessMode: perm_model.AccessModeRead,
|
||||||
@ -43,7 +50,7 @@ func TestHasAnyUnitAccess(t *testing.T) {
|
|||||||
assert.True(t, perm.HasAnyUnitAccess())
|
assert.True(t, perm.HasAnyUnitAccess())
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestApplyEveryoneRepoPermission(t *testing.T) {
|
func TestApplyPublicAccessRepoPermission(t *testing.T) {
|
||||||
perm := Permission{
|
perm := Permission{
|
||||||
AccessMode: perm_model.AccessModeNone,
|
AccessMode: perm_model.AccessModeNone,
|
||||||
units: []*repo_model.RepoUnit{
|
units: []*repo_model.RepoUnit{
|
||||||
@ -53,6 +60,15 @@ func TestApplyEveryoneRepoPermission(t *testing.T) {
|
|||||||
finalProcessRepoUnitPermission(nil, &perm)
|
finalProcessRepoUnitPermission(nil, &perm)
|
||||||
assert.False(t, perm.CanRead(unit.TypeWiki))
|
assert.False(t, perm.CanRead(unit.TypeWiki))
|
||||||
|
|
||||||
|
perm = Permission{
|
||||||
|
AccessMode: perm_model.AccessModeNone,
|
||||||
|
units: []*repo_model.RepoUnit{
|
||||||
|
{Type: unit.TypeWiki, AnonymousAccessMode: perm_model.AccessModeRead},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
finalProcessRepoUnitPermission(nil, &perm)
|
||||||
|
assert.True(t, perm.CanRead(unit.TypeWiki))
|
||||||
|
|
||||||
perm = Permission{
|
perm = Permission{
|
||||||
AccessMode: perm_model.AccessModeNone,
|
AccessMode: perm_model.AccessModeNone,
|
||||||
units: []*repo_model.RepoUnit{
|
units: []*repo_model.RepoUnit{
|
||||||
|
@ -47,6 +47,7 @@ type RepoUnit struct { //revive:disable-line:exported
|
|||||||
Type unit.Type `xorm:"INDEX(s)"`
|
Type unit.Type `xorm:"INDEX(s)"`
|
||||||
Config convert.Conversion `xorm:"TEXT"`
|
Config convert.Conversion `xorm:"TEXT"`
|
||||||
CreatedUnix timeutil.TimeStamp `xorm:"INDEX CREATED"`
|
CreatedUnix timeutil.TimeStamp `xorm:"INDEX CREATED"`
|
||||||
|
AnonymousAccessMode perm.AccessMode `xorm:"NOT NULL DEFAULT 0"`
|
||||||
EveryoneAccessMode perm.AccessMode `xorm:"NOT NULL DEFAULT 0"`
|
EveryoneAccessMode perm.AccessMode `xorm:"NOT NULL DEFAULT 0"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -105,8 +105,6 @@ func Settings(ctx *context.Context) {
|
|||||||
|
|
||||||
// SettingsPost response for changes of a repository
|
// SettingsPost response for changes of a repository
|
||||||
func SettingsPost(ctx *context.Context) {
|
func SettingsPost(ctx *context.Context) {
|
||||||
form := web.GetForm(ctx).(*forms.RepoSettingForm)
|
|
||||||
|
|
||||||
ctx.Data["ForcePrivate"] = setting.Repository.ForcePrivate
|
ctx.Data["ForcePrivate"] = setting.Repository.ForcePrivate
|
||||||
ctx.Data["MirrorsEnabled"] = setting.Mirror.Enabled
|
ctx.Data["MirrorsEnabled"] = setting.Mirror.Enabled
|
||||||
ctx.Data["DisableNewPullMirrors"] = setting.Mirror.DisableNewPull
|
ctx.Data["DisableNewPullMirrors"] = setting.Mirror.DisableNewPull
|
||||||
@ -119,10 +117,55 @@ func SettingsPost(ctx *context.Context) {
|
|||||||
ctx.Data["SigningSettings"] = setting.Repository.Signing
|
ctx.Data["SigningSettings"] = setting.Repository.Signing
|
||||||
ctx.Data["IsRepoIndexerEnabled"] = setting.Indexer.RepoIndexerEnabled
|
ctx.Data["IsRepoIndexerEnabled"] = setting.Indexer.RepoIndexerEnabled
|
||||||
|
|
||||||
repo := ctx.Repo.Repository
|
|
||||||
|
|
||||||
switch ctx.FormString("action") {
|
switch ctx.FormString("action") {
|
||||||
case "update":
|
case "update":
|
||||||
|
handleSettingsPostUpdate(ctx)
|
||||||
|
case "mirror":
|
||||||
|
handleSettingsPostMirror(ctx)
|
||||||
|
case "mirror-sync":
|
||||||
|
handleSettingsPostMirrorSync(ctx)
|
||||||
|
case "push-mirror-sync":
|
||||||
|
handleSettingsPostPushMirrorSync(ctx)
|
||||||
|
case "push-mirror-update":
|
||||||
|
handleSettingsPostPushMirrorUpdate(ctx)
|
||||||
|
case "push-mirror-remove":
|
||||||
|
handleSettingsPostPushMirrorRemove(ctx)
|
||||||
|
case "push-mirror-add":
|
||||||
|
handleSettingsPostPushMirrorAdd(ctx)
|
||||||
|
case "advanced":
|
||||||
|
handleSettingsPostAdvanced(ctx)
|
||||||
|
case "signing":
|
||||||
|
handleSettingsPostSigning(ctx)
|
||||||
|
case "admin":
|
||||||
|
handleSettingsPostAdmin(ctx)
|
||||||
|
case "admin_index":
|
||||||
|
handleSettingsPostAdminIndex(ctx)
|
||||||
|
case "convert":
|
||||||
|
handleSettingsPostConvert(ctx)
|
||||||
|
case "convert_fork":
|
||||||
|
handleSettingsPostConvertFork(ctx)
|
||||||
|
case "transfer":
|
||||||
|
handleSettingsPostTransfer(ctx)
|
||||||
|
case "cancel_transfer":
|
||||||
|
handleSettingsPostCancelTransfer(ctx)
|
||||||
|
case "delete":
|
||||||
|
handleSettingsPostDelete(ctx)
|
||||||
|
case "delete-wiki":
|
||||||
|
handleSettingsPostDeleteWiki(ctx)
|
||||||
|
case "archive":
|
||||||
|
handleSettingsPostArchive(ctx)
|
||||||
|
case "unarchive":
|
||||||
|
handleSettingsPostUnarchive(ctx)
|
||||||
|
case "visibility":
|
||||||
|
handleSettingsPostVisibility(ctx)
|
||||||
|
default:
|
||||||
|
ctx.NotFound(nil)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func handleSettingsPostUpdate(ctx *context.Context) {
|
||||||
|
form := web.GetForm(ctx).(*forms.RepoSettingForm)
|
||||||
|
repo := ctx.Repo.Repository
|
||||||
if ctx.HasError() {
|
if ctx.HasError() {
|
||||||
ctx.HTML(http.StatusOK, tplSettingsOptions)
|
ctx.HTML(http.StatusOK, tplSettingsOptions)
|
||||||
return
|
return
|
||||||
@ -185,8 +228,11 @@ func SettingsPost(ctx *context.Context) {
|
|||||||
|
|
||||||
ctx.Flash.Success(ctx.Tr("repo.settings.update_settings_success"))
|
ctx.Flash.Success(ctx.Tr("repo.settings.update_settings_success"))
|
||||||
ctx.Redirect(repo.Link() + "/settings")
|
ctx.Redirect(repo.Link() + "/settings")
|
||||||
|
}
|
||||||
|
|
||||||
case "mirror":
|
func handleSettingsPostMirror(ctx *context.Context) {
|
||||||
|
form := web.GetForm(ctx).(*forms.RepoSettingForm)
|
||||||
|
repo := ctx.Repo.Repository
|
||||||
if !setting.Mirror.Enabled || !repo.IsMirror || repo.IsArchived {
|
if !setting.Mirror.Enabled || !repo.IsMirror || repo.IsArchived {
|
||||||
ctx.NotFound(nil)
|
ctx.NotFound(nil)
|
||||||
return
|
return
|
||||||
@ -279,8 +325,10 @@ func SettingsPost(ctx *context.Context) {
|
|||||||
|
|
||||||
ctx.Flash.Success(ctx.Tr("repo.settings.update_settings_success"))
|
ctx.Flash.Success(ctx.Tr("repo.settings.update_settings_success"))
|
||||||
ctx.Redirect(repo.Link() + "/settings")
|
ctx.Redirect(repo.Link() + "/settings")
|
||||||
|
}
|
||||||
|
|
||||||
case "mirror-sync":
|
func handleSettingsPostMirrorSync(ctx *context.Context) {
|
||||||
|
repo := ctx.Repo.Repository
|
||||||
if !setting.Mirror.Enabled || !repo.IsMirror || repo.IsArchived {
|
if !setting.Mirror.Enabled || !repo.IsMirror || repo.IsArchived {
|
||||||
ctx.NotFound(nil)
|
ctx.NotFound(nil)
|
||||||
return
|
return
|
||||||
@ -290,8 +338,12 @@ func SettingsPost(ctx *context.Context) {
|
|||||||
|
|
||||||
ctx.Flash.Info(ctx.Tr("repo.settings.pull_mirror_sync_in_progress", repo.OriginalURL))
|
ctx.Flash.Info(ctx.Tr("repo.settings.pull_mirror_sync_in_progress", repo.OriginalURL))
|
||||||
ctx.Redirect(repo.Link() + "/settings")
|
ctx.Redirect(repo.Link() + "/settings")
|
||||||
|
}
|
||||||
|
|
||||||
|
func handleSettingsPostPushMirrorSync(ctx *context.Context) {
|
||||||
|
form := web.GetForm(ctx).(*forms.RepoSettingForm)
|
||||||
|
repo := ctx.Repo.Repository
|
||||||
|
|
||||||
case "push-mirror-sync":
|
|
||||||
if !setting.Mirror.Enabled {
|
if !setting.Mirror.Enabled {
|
||||||
ctx.NotFound(nil)
|
ctx.NotFound(nil)
|
||||||
return
|
return
|
||||||
@ -307,8 +359,12 @@ func SettingsPost(ctx *context.Context) {
|
|||||||
|
|
||||||
ctx.Flash.Info(ctx.Tr("repo.settings.push_mirror_sync_in_progress", m.RemoteAddress))
|
ctx.Flash.Info(ctx.Tr("repo.settings.push_mirror_sync_in_progress", m.RemoteAddress))
|
||||||
ctx.Redirect(repo.Link() + "/settings")
|
ctx.Redirect(repo.Link() + "/settings")
|
||||||
|
}
|
||||||
|
|
||||||
|
func handleSettingsPostPushMirrorUpdate(ctx *context.Context) {
|
||||||
|
form := web.GetForm(ctx).(*forms.RepoSettingForm)
|
||||||
|
repo := ctx.Repo.Repository
|
||||||
|
|
||||||
case "push-mirror-update":
|
|
||||||
if !setting.Mirror.Enabled || repo.IsArchived {
|
if !setting.Mirror.Enabled || repo.IsArchived {
|
||||||
ctx.NotFound(nil)
|
ctx.NotFound(nil)
|
||||||
return
|
return
|
||||||
@ -345,8 +401,12 @@ func SettingsPost(ctx *context.Context) {
|
|||||||
}
|
}
|
||||||
ctx.Flash.Success(ctx.Tr("repo.settings.update_settings_success"))
|
ctx.Flash.Success(ctx.Tr("repo.settings.update_settings_success"))
|
||||||
ctx.Redirect(repo.Link() + "/settings")
|
ctx.Redirect(repo.Link() + "/settings")
|
||||||
|
}
|
||||||
|
|
||||||
|
func handleSettingsPostPushMirrorRemove(ctx *context.Context) {
|
||||||
|
form := web.GetForm(ctx).(*forms.RepoSettingForm)
|
||||||
|
repo := ctx.Repo.Repository
|
||||||
|
|
||||||
case "push-mirror-remove":
|
|
||||||
if !setting.Mirror.Enabled || repo.IsArchived {
|
if !setting.Mirror.Enabled || repo.IsArchived {
|
||||||
ctx.NotFound(nil)
|
ctx.NotFound(nil)
|
||||||
return
|
return
|
||||||
@ -374,8 +434,12 @@ func SettingsPost(ctx *context.Context) {
|
|||||||
|
|
||||||
ctx.Flash.Success(ctx.Tr("repo.settings.update_settings_success"))
|
ctx.Flash.Success(ctx.Tr("repo.settings.update_settings_success"))
|
||||||
ctx.Redirect(repo.Link() + "/settings")
|
ctx.Redirect(repo.Link() + "/settings")
|
||||||
|
}
|
||||||
|
|
||||||
|
func handleSettingsPostPushMirrorAdd(ctx *context.Context) {
|
||||||
|
form := web.GetForm(ctx).(*forms.RepoSettingForm)
|
||||||
|
repo := ctx.Repo.Repository
|
||||||
|
|
||||||
case "push-mirror-add":
|
|
||||||
if setting.Mirror.DisableNewPush || repo.IsArchived {
|
if setting.Mirror.DisableNewPush || repo.IsArchived {
|
||||||
ctx.NotFound(nil)
|
ctx.NotFound(nil)
|
||||||
return
|
return
|
||||||
@ -438,8 +502,11 @@ func SettingsPost(ctx *context.Context) {
|
|||||||
|
|
||||||
ctx.Flash.Success(ctx.Tr("repo.settings.update_settings_success"))
|
ctx.Flash.Success(ctx.Tr("repo.settings.update_settings_success"))
|
||||||
ctx.Redirect(repo.Link() + "/settings")
|
ctx.Redirect(repo.Link() + "/settings")
|
||||||
|
}
|
||||||
|
|
||||||
case "advanced":
|
func handleSettingsPostAdvanced(ctx *context.Context) {
|
||||||
|
form := web.GetForm(ctx).(*forms.RepoSettingForm)
|
||||||
|
repo := ctx.Repo.Repository
|
||||||
var repoChanged bool
|
var repoChanged bool
|
||||||
var units []repo_model.RepoUnit
|
var units []repo_model.RepoUnit
|
||||||
var deleteUnitTypes []unit_model.Type
|
var deleteUnitTypes []unit_model.Type
|
||||||
@ -627,8 +694,11 @@ func SettingsPost(ctx *context.Context) {
|
|||||||
|
|
||||||
ctx.Flash.Success(ctx.Tr("repo.settings.update_settings_success"))
|
ctx.Flash.Success(ctx.Tr("repo.settings.update_settings_success"))
|
||||||
ctx.Redirect(ctx.Repo.RepoLink + "/settings")
|
ctx.Redirect(ctx.Repo.RepoLink + "/settings")
|
||||||
|
}
|
||||||
|
|
||||||
case "signing":
|
func handleSettingsPostSigning(ctx *context.Context) {
|
||||||
|
form := web.GetForm(ctx).(*forms.RepoSettingForm)
|
||||||
|
repo := ctx.Repo.Repository
|
||||||
changed := false
|
changed := false
|
||||||
trustModel := repo_model.ToTrustModel(form.TrustModel)
|
trustModel := repo_model.ToTrustModel(form.TrustModel)
|
||||||
if trustModel != repo.TrustModel {
|
if trustModel != repo.TrustModel {
|
||||||
@ -646,8 +716,11 @@ func SettingsPost(ctx *context.Context) {
|
|||||||
|
|
||||||
ctx.Flash.Success(ctx.Tr("repo.settings.update_settings_success"))
|
ctx.Flash.Success(ctx.Tr("repo.settings.update_settings_success"))
|
||||||
ctx.Redirect(ctx.Repo.RepoLink + "/settings")
|
ctx.Redirect(ctx.Repo.RepoLink + "/settings")
|
||||||
|
}
|
||||||
|
|
||||||
case "admin":
|
func handleSettingsPostAdmin(ctx *context.Context) {
|
||||||
|
form := web.GetForm(ctx).(*forms.RepoSettingForm)
|
||||||
|
repo := ctx.Repo.Repository
|
||||||
if !ctx.Doer.IsAdmin {
|
if !ctx.Doer.IsAdmin {
|
||||||
ctx.HTTPError(http.StatusForbidden)
|
ctx.HTTPError(http.StatusForbidden)
|
||||||
return
|
return
|
||||||
@ -666,8 +739,11 @@ func SettingsPost(ctx *context.Context) {
|
|||||||
|
|
||||||
ctx.Flash.Success(ctx.Tr("repo.settings.update_settings_success"))
|
ctx.Flash.Success(ctx.Tr("repo.settings.update_settings_success"))
|
||||||
ctx.Redirect(ctx.Repo.RepoLink + "/settings")
|
ctx.Redirect(ctx.Repo.RepoLink + "/settings")
|
||||||
|
}
|
||||||
|
|
||||||
case "admin_index":
|
func handleSettingsPostAdminIndex(ctx *context.Context) {
|
||||||
|
form := web.GetForm(ctx).(*forms.RepoSettingForm)
|
||||||
|
repo := ctx.Repo.Repository
|
||||||
if !ctx.Doer.IsAdmin {
|
if !ctx.Doer.IsAdmin {
|
||||||
ctx.HTTPError(http.StatusForbidden)
|
ctx.HTTPError(http.StatusForbidden)
|
||||||
return
|
return
|
||||||
@ -694,8 +770,11 @@ func SettingsPost(ctx *context.Context) {
|
|||||||
|
|
||||||
ctx.Flash.Success(ctx.Tr("repo.settings.reindex_requested"))
|
ctx.Flash.Success(ctx.Tr("repo.settings.reindex_requested"))
|
||||||
ctx.Redirect(ctx.Repo.RepoLink + "/settings")
|
ctx.Redirect(ctx.Repo.RepoLink + "/settings")
|
||||||
|
}
|
||||||
|
|
||||||
case "convert":
|
func handleSettingsPostConvert(ctx *context.Context) {
|
||||||
|
form := web.GetForm(ctx).(*forms.RepoSettingForm)
|
||||||
|
repo := ctx.Repo.Repository
|
||||||
if !ctx.Repo.IsOwner() {
|
if !ctx.Repo.IsOwner() {
|
||||||
ctx.HTTPError(http.StatusNotFound)
|
ctx.HTTPError(http.StatusNotFound)
|
||||||
return
|
return
|
||||||
@ -721,8 +800,11 @@ func SettingsPost(ctx *context.Context) {
|
|||||||
log.Trace("Repository converted from mirror to regular: %s", repo.FullName())
|
log.Trace("Repository converted from mirror to regular: %s", repo.FullName())
|
||||||
ctx.Flash.Success(ctx.Tr("repo.settings.convert_succeed"))
|
ctx.Flash.Success(ctx.Tr("repo.settings.convert_succeed"))
|
||||||
ctx.Redirect(repo.Link())
|
ctx.Redirect(repo.Link())
|
||||||
|
}
|
||||||
|
|
||||||
case "convert_fork":
|
func handleSettingsPostConvertFork(ctx *context.Context) {
|
||||||
|
form := web.GetForm(ctx).(*forms.RepoSettingForm)
|
||||||
|
repo := ctx.Repo.Repository
|
||||||
if !ctx.Repo.IsOwner() {
|
if !ctx.Repo.IsOwner() {
|
||||||
ctx.HTTPError(http.StatusNotFound)
|
ctx.HTTPError(http.StatusNotFound)
|
||||||
return
|
return
|
||||||
@ -758,8 +840,11 @@ func SettingsPost(ctx *context.Context) {
|
|||||||
log.Trace("Repository converted from fork to regular: %s", repo.FullName())
|
log.Trace("Repository converted from fork to regular: %s", repo.FullName())
|
||||||
ctx.Flash.Success(ctx.Tr("repo.settings.convert_fork_succeed"))
|
ctx.Flash.Success(ctx.Tr("repo.settings.convert_fork_succeed"))
|
||||||
ctx.Redirect(repo.Link())
|
ctx.Redirect(repo.Link())
|
||||||
|
}
|
||||||
|
|
||||||
case "transfer":
|
func handleSettingsPostTransfer(ctx *context.Context) {
|
||||||
|
form := web.GetForm(ctx).(*forms.RepoSettingForm)
|
||||||
|
repo := ctx.Repo.Repository
|
||||||
if !ctx.Repo.IsOwner() {
|
if !ctx.Repo.IsOwner() {
|
||||||
ctx.HTTPError(http.StatusNotFound)
|
ctx.HTTPError(http.StatusNotFound)
|
||||||
return
|
return
|
||||||
@ -816,8 +901,10 @@ func SettingsPost(ctx *context.Context) {
|
|||||||
ctx.Flash.Success(ctx.Tr("repo.settings.transfer_succeed"))
|
ctx.Flash.Success(ctx.Tr("repo.settings.transfer_succeed"))
|
||||||
}
|
}
|
||||||
ctx.Redirect(repo.Link() + "/settings")
|
ctx.Redirect(repo.Link() + "/settings")
|
||||||
|
}
|
||||||
|
|
||||||
case "cancel_transfer":
|
func handleSettingsPostCancelTransfer(ctx *context.Context) {
|
||||||
|
repo := ctx.Repo.Repository
|
||||||
if !ctx.Repo.IsOwner() {
|
if !ctx.Repo.IsOwner() {
|
||||||
ctx.HTTPError(http.StatusNotFound)
|
ctx.HTTPError(http.StatusNotFound)
|
||||||
return
|
return
|
||||||
@ -842,8 +929,11 @@ func SettingsPost(ctx *context.Context) {
|
|||||||
log.Trace("Repository transfer process was cancelled: %s/%s ", ctx.Repo.Owner.Name, repo.Name)
|
log.Trace("Repository transfer process was cancelled: %s/%s ", ctx.Repo.Owner.Name, repo.Name)
|
||||||
ctx.Flash.Success(ctx.Tr("repo.settings.transfer_abort_success", repoTransfer.Recipient.Name))
|
ctx.Flash.Success(ctx.Tr("repo.settings.transfer_abort_success", repoTransfer.Recipient.Name))
|
||||||
ctx.Redirect(repo.Link() + "/settings")
|
ctx.Redirect(repo.Link() + "/settings")
|
||||||
|
}
|
||||||
|
|
||||||
case "delete":
|
func handleSettingsPostDelete(ctx *context.Context) {
|
||||||
|
form := web.GetForm(ctx).(*forms.RepoSettingForm)
|
||||||
|
repo := ctx.Repo.Repository
|
||||||
if !ctx.Repo.IsOwner() {
|
if !ctx.Repo.IsOwner() {
|
||||||
ctx.HTTPError(http.StatusNotFound)
|
ctx.HTTPError(http.StatusNotFound)
|
||||||
return
|
return
|
||||||
@ -866,8 +956,11 @@ func SettingsPost(ctx *context.Context) {
|
|||||||
|
|
||||||
ctx.Flash.Success(ctx.Tr("repo.settings.deletion_success"))
|
ctx.Flash.Success(ctx.Tr("repo.settings.deletion_success"))
|
||||||
ctx.Redirect(ctx.Repo.Owner.DashboardLink())
|
ctx.Redirect(ctx.Repo.Owner.DashboardLink())
|
||||||
|
}
|
||||||
|
|
||||||
case "delete-wiki":
|
func handleSettingsPostDeleteWiki(ctx *context.Context) {
|
||||||
|
form := web.GetForm(ctx).(*forms.RepoSettingForm)
|
||||||
|
repo := ctx.Repo.Repository
|
||||||
if !ctx.Repo.IsOwner() {
|
if !ctx.Repo.IsOwner() {
|
||||||
ctx.HTTPError(http.StatusNotFound)
|
ctx.HTTPError(http.StatusNotFound)
|
||||||
return
|
return
|
||||||
@ -885,8 +978,10 @@ func SettingsPost(ctx *context.Context) {
|
|||||||
|
|
||||||
ctx.Flash.Success(ctx.Tr("repo.settings.wiki_deletion_success"))
|
ctx.Flash.Success(ctx.Tr("repo.settings.wiki_deletion_success"))
|
||||||
ctx.Redirect(ctx.Repo.RepoLink + "/settings")
|
ctx.Redirect(ctx.Repo.RepoLink + "/settings")
|
||||||
|
}
|
||||||
|
|
||||||
case "archive":
|
func handleSettingsPostArchive(ctx *context.Context) {
|
||||||
|
repo := ctx.Repo.Repository
|
||||||
if !ctx.Repo.IsOwner() {
|
if !ctx.Repo.IsOwner() {
|
||||||
ctx.HTTPError(http.StatusForbidden)
|
ctx.HTTPError(http.StatusForbidden)
|
||||||
return
|
return
|
||||||
@ -916,8 +1011,10 @@ func SettingsPost(ctx *context.Context) {
|
|||||||
|
|
||||||
log.Trace("Repository was archived: %s/%s", ctx.Repo.Owner.Name, repo.Name)
|
log.Trace("Repository was archived: %s/%s", ctx.Repo.Owner.Name, repo.Name)
|
||||||
ctx.Redirect(ctx.Repo.RepoLink + "/settings")
|
ctx.Redirect(ctx.Repo.RepoLink + "/settings")
|
||||||
|
}
|
||||||
|
|
||||||
case "unarchive":
|
func handleSettingsPostUnarchive(ctx *context.Context) {
|
||||||
|
repo := ctx.Repo.Repository
|
||||||
if !ctx.Repo.IsOwner() {
|
if !ctx.Repo.IsOwner() {
|
||||||
ctx.HTTPError(http.StatusForbidden)
|
ctx.HTTPError(http.StatusForbidden)
|
||||||
return
|
return
|
||||||
@ -943,8 +1040,11 @@ func SettingsPost(ctx *context.Context) {
|
|||||||
|
|
||||||
log.Trace("Repository was un-archived: %s/%s", ctx.Repo.Owner.Name, repo.Name)
|
log.Trace("Repository was un-archived: %s/%s", ctx.Repo.Owner.Name, repo.Name)
|
||||||
ctx.Redirect(ctx.Repo.RepoLink + "/settings")
|
ctx.Redirect(ctx.Repo.RepoLink + "/settings")
|
||||||
|
}
|
||||||
|
|
||||||
case "visibility":
|
func handleSettingsPostVisibility(ctx *context.Context) {
|
||||||
|
form := web.GetForm(ctx).(*forms.RepoSettingForm)
|
||||||
|
repo := ctx.Repo.Repository
|
||||||
if repo.IsFork {
|
if repo.IsFork {
|
||||||
ctx.Flash.Error(ctx.Tr("repo.settings.visibility.fork_error"))
|
ctx.Flash.Error(ctx.Tr("repo.settings.visibility.fork_error"))
|
||||||
ctx.Redirect(ctx.Repo.RepoLink + "/settings")
|
ctx.Redirect(ctx.Repo.RepoLink + "/settings")
|
||||||
@ -976,10 +1076,6 @@ func SettingsPost(ctx *context.Context) {
|
|||||||
|
|
||||||
log.Trace("Repository visibility changed: %s/%s", ctx.Repo.Owner.Name, repo.Name)
|
log.Trace("Repository visibility changed: %s/%s", ctx.Repo.Owner.Name, repo.Name)
|
||||||
ctx.Redirect(ctx.Repo.RepoLink + "/settings")
|
ctx.Redirect(ctx.Repo.RepoLink + "/settings")
|
||||||
|
|
||||||
default:
|
|
||||||
ctx.NotFound(nil)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func handleSettingRemoteAddrError(ctx *context.Context, err error, form *forms.RepoSettingForm) {
|
func handleSettingRemoteAddrError(ctx *context.Context, err error, form *forms.RepoSettingForm) {
|
||||||
|
@ -346,7 +346,7 @@ func repoAssignment(ctx *Context, repo *repo_model.Repository) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if !ctx.Repo.Permission.HasAnyUnitAccessOrEveryoneAccess() && !canWriteAsMaintainer(ctx) {
|
if !ctx.Repo.Permission.HasAnyUnitAccessOrPublicAccess() && !canWriteAsMaintainer(ctx) {
|
||||||
if ctx.FormString("go-get") == "1" {
|
if ctx.FormString("go-get") == "1" {
|
||||||
EarlyResponseForGoGetMeta(ctx)
|
EarlyResponseForGoGetMeta(ctx)
|
||||||
return
|
return
|
||||||
|
Loading…
Reference in New Issue
Block a user