|
7 | 7 | "fmt"
|
8 | 8 | "io"
|
9 | 9 | "net/http"
|
| 10 | + "net/url" |
10 | 11 | "path"
|
11 | 12 | "strings"
|
12 | 13 |
|
@@ -45,6 +46,41 @@ func canCreateBasePullRequest(ctx *context.Context) bool {
|
45 | 46 | return baseRepo != nil && baseRepo.UnitEnabled(ctx, unit.TypePullRequests)
|
46 | 47 | }
|
47 | 48 |
|
| 49 | +// redirectToFork redirects to the user's fork when editing is not possible |
| 50 | +func redirectToFork(ctx *context.Context) bool { |
| 51 | + if ctx.Repo.CanWriteToBranch(ctx, ctx.Doer, ctx.Repo.BranchName) { |
| 52 | + return false |
| 53 | + } |
| 54 | + |
| 55 | + repo := ctx.Repo.Repository |
| 56 | + userAndOrgForks, err := repo_model.GetForksByUserAndOrgs(ctx, ctx.Doer, repo) |
| 57 | + if err != nil { |
| 58 | + ctx.ServerError("GetForksByUserAndOrgs", err) |
| 59 | + return true |
| 60 | + } |
| 61 | + |
| 62 | + // When already on a repo the user owns, don't redirect further even if |
| 63 | + // writing to the branch is not possible. |
| 64 | + for _, forkRepo := range userAndOrgForks { |
| 65 | + if forkRepo.ID == repo.ID { |
| 66 | + ctx.NotFound(nil) |
| 67 | + return true |
| 68 | + } |
| 69 | + } |
| 70 | + |
| 71 | + link := setting.AppSubURL + ctx.Req.URL.RequestURI() |
| 72 | + if len(userAndOrgForks) > 0 { |
| 73 | + // Redirect to user repository |
| 74 | + forkRepo := userAndOrgForks[0] |
| 75 | + ctx.Redirect(repo.AdaptLinkToFork(forkRepo, link)) |
| 76 | + } else { |
| 77 | + // Redirect to create new user repository |
| 78 | + ctx.Redirect(repo.Link() + "/fork/?redirect_to_edit=" + url.QueryEscape(link)) |
| 79 | + } |
| 80 | + |
| 81 | + return true |
| 82 | +} |
| 83 | + |
48 | 84 | func renderCommitRights(ctx *context.Context) bool {
|
49 | 85 | canCommitToBranch, err := ctx.Repo.CanCommitToBranch(ctx, ctx.Doer)
|
50 | 86 | if err != nil {
|
@@ -213,11 +249,19 @@ func GetEditorConfig(ctx *context.Context, treePath string) string {
|
213 | 249 |
|
214 | 250 | // EditFile render edit file page
|
215 | 251 | func EditFile(ctx *context.Context) {
|
| 252 | + if redirectToFork(ctx) { |
| 253 | + return |
| 254 | + } |
| 255 | + |
216 | 256 | editFile(ctx, false)
|
217 | 257 | }
|
218 | 258 |
|
219 | 259 | // NewFile render create file page
|
220 | 260 | func NewFile(ctx *context.Context) {
|
| 261 | + if redirectToFork(ctx) { |
| 262 | + return |
| 263 | + } |
| 264 | + |
221 | 265 | editFile(ctx, true)
|
222 | 266 | }
|
223 | 267 |
|
@@ -431,6 +475,10 @@ func DiffPreviewPost(ctx *context.Context) {
|
431 | 475 |
|
432 | 476 | // DeleteFile render delete file page
|
433 | 477 | func DeleteFile(ctx *context.Context) {
|
| 478 | + if redirectToFork(ctx) { |
| 479 | + return |
| 480 | + } |
| 481 | + |
434 | 482 | ctx.Data["PageIsDelete"] = true
|
435 | 483 | ctx.Data["BranchLink"] = ctx.Repo.RepoLink + "/src/" + ctx.Repo.RefTypeNameSubURL()
|
436 | 484 | treePath := cleanUploadFileName(ctx.Repo.TreePath)
|
@@ -599,6 +647,10 @@ func DeleteFilePost(ctx *context.Context) {
|
599 | 647 |
|
600 | 648 | // UploadFile render upload file page
|
601 | 649 | func UploadFile(ctx *context.Context) {
|
| 650 | + if redirectToFork(ctx) { |
| 651 | + return |
| 652 | + } |
| 653 | + |
602 | 654 | ctx.Data["PageIsUpload"] = true
|
603 | 655 | upload.AddUploadContext(ctx, "repo")
|
604 | 656 | canCommit := renderCommitRights(ctx)
|
|
0 commit comments