Merge pull request 'Allow pushmirror to use publickey authentication' (#4819) from ironmagma/forgejo:publickey-auth-push-mirror into forgejo

Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/4819
Reviewed-by: Earl Warren <earl-warren@noreply.codeberg.org>
This commit is contained in:
Gusted 2024-08-24 16:53:56 +00:00
commit 5dbacb70f4
24 changed files with 648 additions and 66 deletions

View file

@ -350,6 +350,11 @@ func CreatePushMirror(ctx *context.APIContext, mirrorOption *api.CreatePushMirro
return
}
if mirrorOption.UseSSH && (mirrorOption.RemoteUsername != "" || mirrorOption.RemotePassword != "") {
ctx.Error(http.StatusBadRequest, "CreatePushMirror", "'use_ssh' is mutually exclusive with 'remote_username' and 'remote_passoword'")
return
}
address, err := forms.ParseRemoteAddr(mirrorOption.RemoteAddress, mirrorOption.RemoteUsername, mirrorOption.RemotePassword)
if err == nil {
err = migrations.IsMigrateURLAllowed(address, ctx.ContextUser)
@ -365,7 +370,7 @@ func CreatePushMirror(ctx *context.APIContext, mirrorOption *api.CreatePushMirro
return
}
remoteAddress, err := util.SanitizeURL(mirrorOption.RemoteAddress)
remoteAddress, err := util.SanitizeURL(address)
if err != nil {
ctx.ServerError("SanitizeURL", err)
return
@ -380,11 +385,29 @@ func CreatePushMirror(ctx *context.APIContext, mirrorOption *api.CreatePushMirro
RemoteAddress: remoteAddress,
}
var plainPrivateKey []byte
if mirrorOption.UseSSH {
publicKey, privateKey, err := util.GenerateSSHKeypair()
if err != nil {
ctx.ServerError("GenerateSSHKeypair", err)
return
}
plainPrivateKey = privateKey
pushMirror.PublicKey = string(publicKey)
}
if err = db.Insert(ctx, pushMirror); err != nil {
ctx.ServerError("InsertPushMirror", err)
return
}
if mirrorOption.UseSSH {
if err = pushMirror.SetPrivatekey(ctx, plainPrivateKey); err != nil {
ctx.ServerError("SetPrivatekey", err)
return
}
}
// if the registration of the push mirrorOption fails remove it from the database
if err = mirror_service.AddPushMirrorRemote(ctx, pushMirror, address); err != nil {
if err := repo_model.DeletePushMirrors(ctx, repo_model.PushMirrorOptions{ID: pushMirror.ID, RepoID: pushMirror.RepoID}); err != nil {

View file

@ -478,8 +478,7 @@ func SettingsPost(ctx *context.Context) {
ctx.ServerError("UpdateAddress", err)
return
}
remoteAddress, err := util.SanitizeURL(form.MirrorAddress)
remoteAddress, err := util.SanitizeURL(address)
if err != nil {
ctx.ServerError("SanitizeURL", err)
return
@ -638,6 +637,12 @@ func SettingsPost(ctx *context.Context) {
return
}
if form.PushMirrorUseSSH && (form.PushMirrorUsername != "" || form.PushMirrorPassword != "") {
ctx.Data["Err_PushMirrorUseSSH"] = true
ctx.RenderWithErr(ctx.Tr("repo.mirror_denied_combination"), tplSettingsOptions, &form)
return
}
address, err := forms.ParseRemoteAddr(form.PushMirrorAddress, form.PushMirrorUsername, form.PushMirrorPassword)
if err == nil {
err = migrations.IsMigrateURLAllowed(address, ctx.Doer)
@ -654,7 +659,7 @@ func SettingsPost(ctx *context.Context) {
return
}
remoteAddress, err := util.SanitizeURL(form.PushMirrorAddress)
remoteAddress, err := util.SanitizeURL(address)
if err != nil {
ctx.ServerError("SanitizeURL", err)
return
@ -668,11 +673,30 @@ func SettingsPost(ctx *context.Context) {
Interval: interval,
RemoteAddress: remoteAddress,
}
var plainPrivateKey []byte
if form.PushMirrorUseSSH {
publicKey, privateKey, err := util.GenerateSSHKeypair()
if err != nil {
ctx.ServerError("GenerateSSHKeypair", err)
return
}
plainPrivateKey = privateKey
m.PublicKey = string(publicKey)
}
if err := db.Insert(ctx, m); err != nil {
ctx.ServerError("InsertPushMirror", err)
return
}
if form.PushMirrorUseSSH {
if err := m.SetPrivatekey(ctx, plainPrivateKey); err != nil {
ctx.ServerError("SetPrivatekey", err)
return
}
}
if err := mirror_service.AddPushMirrorRemote(ctx, m, address); err != nil {
if err := repo_model.DeletePushMirrors(ctx, repo_model.PushMirrorOptions{ID: m.ID, RepoID: m.RepoID}); err != nil {
log.Error("DeletePushMirrors %v", err)