diff --git a/integrations/api_repo_test.go b/integrations/api_repo_test.go
index 12429c88a8..c789cc9ee4 100644
--- a/integrations/api_repo_test.go
+++ b/integrations/api_repo_test.go
@@ -235,3 +235,30 @@ func TestAPIGetRepoByIDUnauthorized(t *testing.T) {
 	req := NewRequestf(t, "GET", "/api/v1/repositories/2")
 	sess.MakeRequest(t, req, http.StatusNotFound)
 }
+
+func TestAPIRepoMigrate(t *testing.T) {
+	testCases := []struct {
+		ctxUserID, userID  int64
+		cloneURL, repoName string
+		expectedStatus     int
+	}{
+		{ctxUserID: 1, userID: 2, cloneURL: "https://github.com/go-gitea/git.git", repoName: "git-admin", expectedStatus: http.StatusCreated},
+		{ctxUserID: 2, userID: 2, cloneURL: "https://github.com/go-gitea/git.git", repoName: "git-own", expectedStatus: http.StatusCreated},
+		{ctxUserID: 2, userID: 1, cloneURL: "https://github.com/go-gitea/git.git", repoName: "git-bad", expectedStatus: http.StatusForbidden},
+		{ctxUserID: 2, userID: 3, cloneURL: "https://github.com/go-gitea/git.git", repoName: "git-org", expectedStatus: http.StatusCreated},
+		{ctxUserID: 2, userID: 6, cloneURL: "https://github.com/go-gitea/git.git", repoName: "git-bad-org", expectedStatus: http.StatusForbidden},
+	}
+
+	prepareTestEnv(t)
+	for _, testCase := range testCases {
+		user := models.AssertExistsAndLoadBean(t, &models.User{ID: testCase.ctxUserID}).(*models.User)
+		session := loginUser(t, user.Name)
+
+		req := NewRequestWithJSON(t, "POST", "/api/v1/repos/migrate", &api.MigrateRepoOption{
+			CloneAddr: testCase.cloneURL,
+			UID:       int(testCase.userID),
+			RepoName:  testCase.repoName,
+		})
+		session.MakeRequest(t, req, testCase.expectedStatus)
+	}
+}
diff --git a/routers/api/v1/repo/repo.go b/routers/api/v1/repo/repo.go
index ccfe0440c8..c6c5d4aec3 100644
--- a/routers/api/v1/repo/repo.go
+++ b/routers/api/v1/repo/repo.go
@@ -306,16 +306,23 @@ func Migrate(ctx *context.APIContext, form auth.MigrateRepoForm) {
 		return
 	}
 
-	if ctxUser.IsOrganization() && !ctx.User.IsAdmin {
-		// Check ownership of organization.
-		isOwner, err := ctxUser.IsOwnedBy(ctx.User.ID)
-		if err != nil {
-			ctx.Error(500, "IsOwnedBy", err)
-			return
-		} else if !isOwner {
-			ctx.Error(403, "", "Given user is not owner of organization.")
+	if !ctx.User.IsAdmin {
+		if !ctxUser.IsOrganization() && ctx.User.ID != ctxUser.ID {
+			ctx.Error(403, "", "Given user is not an organization.")
 			return
 		}
+
+		if ctxUser.IsOrganization() {
+			// Check ownership of organization.
+			isOwner, err := ctxUser.IsOwnedBy(ctx.User.ID)
+			if err != nil {
+				ctx.Error(500, "IsOwnedBy", err)
+				return
+			} else if !isOwner {
+				ctx.Error(403, "", "Given user is not owner of organization.")
+				return
+			}
+		}
 	}
 
 	remoteAddr, err := form.ParseRemoteAddr(ctx.User)