SSH Push/Pull Mirroring & Migrations

This commit is contained in:
techknowlogick
2025-07-15 15:46:17 -04:00
parent 9854df3e87
commit 4c8e222242
30 changed files with 1495 additions and 28 deletions
+10
View File
@@ -1161,6 +1161,11 @@ func Routes() *web.Router {
m.Delete("", user.UnblockUser)
}, context.UserAssignmentAPI(), checkTokenPublicOnly())
})
m.Group("/mirror-ssh-key", func() {
m.Get("", user.GetMirrorSSHKey)
m.Post("/regenerate", user.RegenerateMirrorSSHKey)
})
}, tokenRequiresScopes(auth_model.AccessTokenScopeCategoryUser), reqToken())
// Repositories (requires repo scope, org scope)
@@ -1687,6 +1692,11 @@ func Routes() *web.Router {
m.Delete("", org.UnblockUser)
})
}, reqToken(), reqOrgOwnership())
m.Group("/mirror-ssh-key", func() {
m.Get("", reqToken(), reqOrgMembership(), org.GetMirrorSSHKey)
m.Post("/regenerate", reqToken(), reqOrgOwnership(), org.RegenerateMirrorSSHKey)
})
}, tokenRequiresScopes(auth_model.AccessTokenScopeCategoryOrganization), orgAssignment(true), checkTokenPublicOnly())
m.Group("/teams/{teamid}", func() {
m.Combo("").Get(reqToken(), org.GetTeam).
+96
View File
@@ -0,0 +1,96 @@
// Copyright 2025 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package org
import (
"net/http"
"code.gitea.io/gitea/models/db"
"code.gitea.io/gitea/services/context"
mirror_service "code.gitea.io/gitea/services/mirror"
)
// GetMirrorSSHKey gets the SSH public key for organization mirroring
func GetMirrorSSHKey(ctx *context.APIContext) {
// swagger:operation GET /orgs/{org}/mirror-ssh-key organization orgGetMirrorSSHKey
// ---
// summary: Get SSH public key for organization mirroring
// produces:
// - application/json
// parameters:
// - name: org
// in: path
// description: name of the organization
// type: string
// required: true
// responses:
// "200":
// description: SSH public key
// schema:
// type: object
// properties:
// public_key:
// type: string
// fingerprint:
// type: string
// "403":
// "$ref": "#/responses/forbidden"
// "404":
// "$ref": "#/responses/notFound"
keypair, err := mirror_service.GetOrCreateSSHKeypairForOrg(ctx, ctx.Org.Organization.ID)
if err != nil {
if db.IsErrNotExist(err) {
ctx.APIError(http.StatusNotFound, "SSH keypair not found")
return
}
ctx.APIErrorInternal(err)
return
}
ctx.JSON(http.StatusOK, map[string]string{
"public_key": keypair.PublicKey,
"fingerprint": keypair.Fingerprint,
})
}
// RegenerateMirrorSSHKey regenerates the SSH keypair for organization mirroring
func RegenerateMirrorSSHKey(ctx *context.APIContext) {
// swagger:operation POST /orgs/{org}/mirror-ssh-key/regenerate organization orgRegenerateMirrorSSHKey
// ---
// summary: Regenerate SSH keypair for organization mirroring
// produces:
// - application/json
// parameters:
// - name: org
// in: path
// description: name of the organization
// type: string
// required: true
// responses:
// "200":
// description: New SSH public key
// schema:
// type: object
// properties:
// public_key:
// type: string
// fingerprint:
// type: string
// "403":
// "$ref": "#/responses/forbidden"
// "500":
// "$ref": "#/responses/internalServerError"
keypair, err := mirror_service.RegenerateSSHKeypairForOrg(ctx, ctx.Org.Organization.ID)
if err != nil {
ctx.APIErrorInternal(err)
return
}
ctx.JSON(http.StatusOK, map[string]string{
"public_key": keypair.PublicKey,
"fingerprint": keypair.Fingerprint,
})
}
+80
View File
@@ -0,0 +1,80 @@
// Copyright 2025 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package user
import (
"net/http"
"code.gitea.io/gitea/models/db"
"code.gitea.io/gitea/services/context"
mirror_service "code.gitea.io/gitea/services/mirror"
)
// GetMirrorSSHKey gets the SSH public key for user mirroring
func GetMirrorSSHKey(ctx *context.APIContext) {
// swagger:operation GET /user/mirror-ssh-key user userGetMirrorSSHKey
// ---
// summary: Get SSH public key for user mirroring
// produces:
// - application/json
// responses:
// "200":
// description: SSH public key
// schema:
// type: object
// properties:
// public_key:
// type: string
// fingerprint:
// type: string
// "404":
// "$ref": "#/responses/notFound"
keypair, err := mirror_service.GetOrCreateSSHKeypairForUser(ctx, ctx.Doer.ID)
if err != nil {
if db.IsErrNotExist(err) {
ctx.APIError(http.StatusNotFound, "SSH keypair not found")
return
}
ctx.APIErrorInternal(err)
return
}
ctx.JSON(http.StatusOK, map[string]string{
"public_key": keypair.PublicKey,
"fingerprint": keypair.Fingerprint,
})
}
// RegenerateMirrorSSHKey regenerates the SSH keypair for user mirroring
func RegenerateMirrorSSHKey(ctx *context.APIContext) {
// swagger:operation POST /user/mirror-ssh-key/regenerate user userRegenerateMirrorSSHKey
// ---
// summary: Regenerate SSH keypair for user mirroring
// produces:
// - application/json
// responses:
// "200":
// description: New SSH public key
// schema:
// type: object
// properties:
// public_key:
// type: string
// fingerprint:
// type: string
// "500":
// "$ref": "#/responses/internalServerError"
keypair, err := mirror_service.RegenerateSSHKeypairForUser(ctx, ctx.Doer.ID)
if err != nil {
ctx.APIErrorInternal(err)
return
}
ctx.JSON(http.StatusOK, map[string]string{
"public_key": keypair.PublicKey,
"fingerprint": keypair.Fingerprint,
})
}