mirror of
				https://github.com/go-gitea/gitea.git
				synced 2025-10-26 12:27:06 +00:00 
			
		
		
		
	Fix javascript error when an anonymous user visiting migration page (#32144)
This PR fixes javascript errors when an anonymous user visits the
migration page.
It also makes task view checking more restrictive.
The router moved from `/user/task/{id}/status` to
`/username/reponame/-/migrate/status` because it's a migrate status.
---------
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
			
			
This commit is contained in:
		| @@ -179,27 +179,6 @@ func GetMigratingTask(ctx context.Context, repoID int64) (*Task, error) { | ||||
| 	return &task, nil | ||||
| } | ||||
|  | ||||
| // GetMigratingTaskByID returns the migrating task by repo's id | ||||
| func GetMigratingTaskByID(ctx context.Context, id, doerID int64) (*Task, *migration.MigrateOptions, error) { | ||||
| 	task := Task{ | ||||
| 		ID:     id, | ||||
| 		DoerID: doerID, | ||||
| 		Type:   structs.TaskTypeMigrateRepo, | ||||
| 	} | ||||
| 	has, err := db.GetEngine(ctx).Get(&task) | ||||
| 	if err != nil { | ||||
| 		return nil, nil, err | ||||
| 	} else if !has { | ||||
| 		return nil, nil, ErrTaskDoesNotExist{id, 0, task.Type} | ||||
| 	} | ||||
|  | ||||
| 	var opts migration.MigrateOptions | ||||
| 	if err := json.Unmarshal([]byte(task.PayloadContent), &opts); err != nil { | ||||
| 		return nil, nil, err | ||||
| 	} | ||||
| 	return &task, &opts, nil | ||||
| } | ||||
|  | ||||
| // CreateTask creates a task on database | ||||
| func CreateTask(ctx context.Context, task *Task) error { | ||||
| 	return db.Insert(ctx, task) | ||||
|   | ||||
| @@ -15,6 +15,7 @@ import ( | ||||
| 	repo_model "code.gitea.io/gitea/models/repo" | ||||
| 	user_model "code.gitea.io/gitea/models/user" | ||||
| 	"code.gitea.io/gitea/modules/base" | ||||
| 	"code.gitea.io/gitea/modules/json" | ||||
| 	"code.gitea.io/gitea/modules/lfs" | ||||
| 	"code.gitea.io/gitea/modules/log" | ||||
| 	"code.gitea.io/gitea/modules/setting" | ||||
| @@ -288,3 +289,40 @@ func MigrateCancelPost(ctx *context.Context) { | ||||
| 	} | ||||
| 	ctx.Redirect(ctx.Repo.Repository.Link()) | ||||
| } | ||||
|  | ||||
| // MigrateStatus returns migrate task's status | ||||
| func MigrateStatus(ctx *context.Context) { | ||||
| 	task, err := admin_model.GetMigratingTask(ctx, ctx.Repo.Repository.ID) | ||||
| 	if err != nil { | ||||
| 		if admin_model.IsErrTaskDoesNotExist(err) { | ||||
| 			ctx.JSON(http.StatusNotFound, map[string]any{ | ||||
| 				"err": "task does not exist or you do not have access to this task", | ||||
| 			}) | ||||
| 			return | ||||
| 		} | ||||
| 		log.Error("GetMigratingTask: %v", err) | ||||
| 		ctx.JSON(http.StatusInternalServerError, map[string]any{ | ||||
| 			"err": http.StatusText(http.StatusInternalServerError), | ||||
| 		}) | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	message := task.Message | ||||
|  | ||||
| 	if task.Message != "" && task.Message[0] == '{' { | ||||
| 		// assume message is actually a translatable string | ||||
| 		var translatableMessage admin_model.TranslatableMessage | ||||
| 		if err := json.Unmarshal([]byte(message), &translatableMessage); err != nil { | ||||
| 			translatableMessage = admin_model.TranslatableMessage{ | ||||
| 				Format: "migrate.migrating_failed.error", | ||||
| 				Args:   []any{task.Message}, | ||||
| 			} | ||||
| 		} | ||||
| 		message = ctx.Locale.TrString(translatableMessage.Format, translatableMessage.Args...) | ||||
| 	} | ||||
|  | ||||
| 	ctx.JSON(http.StatusOK, map[string]any{ | ||||
| 		"status":  task.Status, | ||||
| 		"message": message, | ||||
| 	}) | ||||
| } | ||||
|   | ||||
| @@ -1,53 +0,0 @@ | ||||
| // Copyright 2020 The Gitea Authors. All rights reserved. | ||||
| // SPDX-License-Identifier: MIT | ||||
|  | ||||
| package user | ||||
|  | ||||
| import ( | ||||
| 	"net/http" | ||||
| 	"strconv" | ||||
|  | ||||
| 	admin_model "code.gitea.io/gitea/models/admin" | ||||
| 	"code.gitea.io/gitea/modules/json" | ||||
| 	"code.gitea.io/gitea/services/context" | ||||
| ) | ||||
|  | ||||
| // TaskStatus returns task's status | ||||
| func TaskStatus(ctx *context.Context) { | ||||
| 	task, opts, err := admin_model.GetMigratingTaskByID(ctx, ctx.PathParamInt64("task"), ctx.Doer.ID) | ||||
| 	if err != nil { | ||||
| 		if admin_model.IsErrTaskDoesNotExist(err) { | ||||
| 			ctx.JSON(http.StatusNotFound, map[string]any{ | ||||
| 				"error": "task `" + strconv.FormatInt(ctx.PathParamInt64("task"), 10) + "` does not exist", | ||||
| 			}) | ||||
| 			return | ||||
| 		} | ||||
| 		ctx.JSON(http.StatusInternalServerError, map[string]any{ | ||||
| 			"err": err, | ||||
| 		}) | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	message := task.Message | ||||
|  | ||||
| 	if task.Message != "" && task.Message[0] == '{' { | ||||
| 		// assume message is actually a translatable string | ||||
| 		var translatableMessage admin_model.TranslatableMessage | ||||
| 		if err := json.Unmarshal([]byte(message), &translatableMessage); err != nil { | ||||
| 			translatableMessage = admin_model.TranslatableMessage{ | ||||
| 				Format: "migrate.migrating_failed.error", | ||||
| 				Args:   []any{task.Message}, | ||||
| 			} | ||||
| 		} | ||||
| 		message = ctx.Locale.TrString(translatableMessage.Format, translatableMessage.Args...) | ||||
| 	} | ||||
|  | ||||
| 	ctx.JSON(http.StatusOK, map[string]any{ | ||||
| 		"status":    task.Status, | ||||
| 		"message":   message, | ||||
| 		"repo-id":   task.RepoID, | ||||
| 		"repo-name": opts.RepoName, | ||||
| 		"start":     task.StartTime, | ||||
| 		"end":       task.EndTime, | ||||
| 	}) | ||||
| } | ||||
| @@ -669,7 +669,6 @@ func registerRoutes(m *web.Router) { | ||||
| 		m.Get("/forgot_password", auth.ForgotPasswd) | ||||
| 		m.Post("/forgot_password", auth.ForgotPasswdPost) | ||||
| 		m.Post("/logout", auth.SignOut) | ||||
| 		m.Get("/task/{task}", reqSignIn, user.TaskStatus) | ||||
| 		m.Get("/stopwatches", reqSignIn, user.GetStopwatches) | ||||
| 		m.Get("/search", ignExploreSignIn, user.Search) | ||||
| 		m.Group("/oauth2", func() { | ||||
| @@ -1042,6 +1041,13 @@ func registerRoutes(m *web.Router) { | ||||
| 	}, ignSignIn, context.UserAssignmentWeb(), context.OrgAssignment()) | ||||
| 	// end "/{username}/-": packages, projects, code | ||||
|  | ||||
| 	m.Group("/{username}/{reponame}/-", func() { | ||||
| 		m.Group("/migrate", func() { | ||||
| 			m.Get("/status", repo.MigrateStatus) | ||||
| 		}) | ||||
| 	}, ignSignIn, context.RepoAssignment, reqRepoCodeReader) | ||||
| 	// end "/{username}/{reponame}/-": migrate | ||||
|  | ||||
| 	m.Group("/{username}/{reponame}/settings", func() { | ||||
| 		m.Group("", func() { | ||||
| 			m.Combo("").Get(repo_setting.Settings). | ||||
|   | ||||
| @@ -614,7 +614,10 @@ func RepoAssignment(ctx *Context) context.CancelFunc { | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	isHomeOrSettings := ctx.Link == ctx.Repo.RepoLink || ctx.Link == ctx.Repo.RepoLink+"/settings" || strings.HasPrefix(ctx.Link, ctx.Repo.RepoLink+"/settings/") | ||||
| 	isHomeOrSettings := ctx.Link == ctx.Repo.RepoLink || | ||||
| 		ctx.Link == ctx.Repo.RepoLink+"/settings" || | ||||
| 		strings.HasPrefix(ctx.Link, ctx.Repo.RepoLink+"/settings/") || | ||||
| 		ctx.Link == ctx.Repo.RepoLink+"/-/migrate/status" | ||||
|  | ||||
| 	// Disable everything when the repo is being created | ||||
| 	if ctx.Repo.Repository.IsBeingCreated() || ctx.Repo.Repository.IsBroken() { | ||||
|   | ||||
| @@ -7,7 +7,7 @@ | ||||
| 				{{template "base/alert" .}} | ||||
| 				<div class="home"> | ||||
| 					<div class="ui stackable middle very relaxed page grid"> | ||||
| 						<div id="repo_migrating" class="sixteen wide center aligned centered column" data-migrating-task-id="{{.MigrateTask.ID}}"> | ||||
| 						<div id="repo_migrating" class="sixteen wide center aligned centered column" data-migrating-repo-link="{{.Link}}"> | ||||
| 							<div> | ||||
| 								<img src="{{AssetUrlPrefix}}/img/loading.png"> | ||||
| 							</div> | ||||
|   | ||||
| @@ -1,19 +1,17 @@ | ||||
| import {hideElem, showElem} from '../utils/dom.ts'; | ||||
| import {GET, POST} from '../modules/fetch.ts'; | ||||
|  | ||||
| const {appSubUrl} = window.config; | ||||
|  | ||||
| export function initRepoMigrationStatusChecker() { | ||||
|   const repoMigrating = document.querySelector('#repo_migrating'); | ||||
|   if (!repoMigrating) return; | ||||
|  | ||||
|   document.querySelector('#repo_migrating_retry').addEventListener('click', doMigrationRetry); | ||||
|   document.querySelector('#repo_migrating_retry')?.addEventListener('click', doMigrationRetry); | ||||
|  | ||||
|   const task = repoMigrating.getAttribute('data-migrating-task-id'); | ||||
|   const repoLink = repoMigrating.getAttribute('data-migrating-repo-link'); | ||||
|  | ||||
|   // returns true if the refresh still needs to be called after a while | ||||
|   const refresh = async () => { | ||||
|     const res = await GET(`${appSubUrl}/user/task/${task}`); | ||||
|     const res = await GET(`${repoLink}/-/migrate/status`); | ||||
|     if (res.status !== 200) return true; // continue to refresh if network error occurs | ||||
|  | ||||
|     const data = await res.json(); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Lunny Xiao
					Lunny Xiao