@@ -8,12 +8,15 @@ import (
88 "fmt"
99
1010 actions_model "code.gitea.io/gitea/models/actions"
11+ activities_model "code.gitea.io/gitea/models/activities"
1112 "code.gitea.io/gitea/models/db"
1213 org_model "code.gitea.io/gitea/models/organization"
1314 packages_model "code.gitea.io/gitea/models/packages"
15+ access_model "code.gitea.io/gitea/models/perm/access"
1416 repo_model "code.gitea.io/gitea/models/repo"
1517 secret_model "code.gitea.io/gitea/models/secret"
1618 user_model "code.gitea.io/gitea/models/user"
19+ issue_indexer "code.gitea.io/gitea/modules/indexer/issues"
1720 "code.gitea.io/gitea/modules/storage"
1821 "code.gitea.io/gitea/modules/structs"
1922 "code.gitea.io/gitea/modules/util"
@@ -104,13 +107,69 @@ func DeleteOrganization(ctx context.Context, org *org_model.Organization, purge
104107 return nil
105108}
106109
110+ func updateOrgRepoForVisibilityChanged (ctx context.Context , repo * repo_model.Repository , makePrivate bool ) error {
111+ // Organization repository need to recalculate access table when visibility is changed.
112+ if err := access_model .RecalculateTeamAccesses (ctx , repo , 0 ); err != nil {
113+ return fmt .Errorf ("recalculateTeamAccesses: %w" , err )
114+ }
115+
116+ if makePrivate {
117+ if _ , err := db .GetEngine (ctx ).Where ("repo_id = ?" , repo .ID ).Cols ("is_private" ).Update (& activities_model.Action {
118+ IsPrivate : true ,
119+ }); err != nil {
120+ return err
121+ }
122+
123+ if err := repo_model .ClearRepoStars (ctx , repo .ID ); err != nil {
124+ return err
125+ }
126+ }
127+
128+ // Create/Remove git-daemon-export-ok for git-daemon...
129+ if err := repo_service .CheckDaemonExportOK (ctx , repo ); err != nil {
130+ return err
131+ }
132+
133+ // If visibility is changed, we need to update the issue indexer.
134+ // Since the data in the issue indexer have field to indicate if the repo is public or not.
135+ // FIXME: it should check organization visibility instead of repository visibility only.
136+ issue_indexer .UpdateRepoIndexer (ctx , repo .ID )
137+
138+ forkRepos , err := repo_model .GetRepositoriesByForkID (ctx , repo .ID )
139+ if err != nil {
140+ return fmt .Errorf ("getRepositoriesByForkID: %w" , err )
141+ }
142+ for i := range forkRepos {
143+ if err := updateOrgRepoForVisibilityChanged (ctx , forkRepos [i ], makePrivate ); err != nil {
144+ return fmt .Errorf ("updateRepoForVisibilityChanged[%d]: %w" , forkRepos [i ], err )
145+ }
146+ }
147+ return nil
148+ }
149+
107150func ChangeOrganizationVisibility (ctx context.Context , org * org_model.Organization , visibility structs.VisibleType ) error {
108151 if org .Visibility == visibility {
109152 return nil
110153 }
111154
112155 org .Visibility = visibility
156+ // FIXME: If it's a big forks network(forks and sub forks), the database transaction will be too long to fail.
113157 return db .WithTx (ctx , func (ctx context.Context ) error {
114- return user_model .UpdateUserColsWithNoAutotime (ctx , org .AsUser (), "visibility" )
158+ if err := user_model .UpdateUserColsWithNoAutotime (ctx , org .AsUser (), "visibility" ); err != nil {
159+ return err
160+ }
161+
162+ repos , _ , err := repo_model .GetUserRepositories (ctx , repo_model.SearchRepoOptions {
163+ Actor : org .AsUser (), Private : true , ListOptions : db .ListOptionsAll ,
164+ })
165+ if err != nil {
166+ return err
167+ }
168+ for _ , repo := range repos {
169+ if err := updateOrgRepoForVisibilityChanged (ctx , repo , visibility == structs .VisibleTypePrivate ); err != nil {
170+ return fmt .Errorf ("updateOrgRepoForVisibilityChanged: %w" , err )
171+ }
172+ }
173+ return nil
115174 })
116175}
0 commit comments