mirror of
https://github.com/go-gitea/gitea.git
synced 2026-09-23 11:06:47 +02:00
SSH Push/Pull Mirroring & Migrations
This commit is contained in:
@@ -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).
|
||||
|
||||
@@ -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,
|
||||
})
|
||||
}
|
||||
@@ -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,
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user