Browse Source

Add multiweb functionality and improve error management.

webdeploy
pebles 2 years ago
parent
commit
b50cafed7f
Signed by: pebles
GPG Key ID: 4501C52A9268B49C
  1. 8
      gitea/gitea.go
  2. 7
      gitea/webhook.go
  3. 172
      server/gitea.go
  4. 144
      tmpl/gitea.html
  5. 2
      tmpl/index.html

8
gitea/gitea.go

@ -67,8 +67,8 @@ func (g *Gitea) Repo(user string, repo string) (*Repo, error) {
}, nil
}
// userID check users exists and return user id
func (r *Repo) userID() (int, error) {
// UserID check users exists and return user id
func (r *Repo) UserID() (int, error) {
userexist, err := r.client.SearchUsers(r.user, 1)
if err != nil {
return -1, err
@ -76,7 +76,6 @@ func (r *Repo) userID() (int, error) {
emptyuser := []*gitea.User{}
if reflect.DeepEqual(userexist, emptyuser) == true {
log.Printf("User doesn't exist")
return -2, err
}
uid := int(userexist[0].ID)
@ -101,7 +100,7 @@ func (r *Repo) Delete() error {
// Migrate template repo to new user repo
func (r *Repo) Migrate() error {
uid, err := r.userID()
uid, err := r.UserID()
if err != nil {
return err
}
@ -149,3 +148,4 @@ func (r *Repo) CreateWebhook() error {
return nil
}

7
gitea/webhook.go

@ -9,16 +9,17 @@ import (
"strings"
)
func (g *Gitea) WebhookDeploy(user, repo, keypriv, keypub string) error {
func (g *Gitea) WebhookDeploy(user, repo, multiweb, keypriv, keypub string) error {
type WebhookData struct {
USER string
REPO string
MULTIWEB string
PUB string
KEY string
SECRET string
}
keypriv = strings.Replace(keypriv, "\n", "|", -1) // key to oneline string, no breaks, '|' (pipe) is newline.
whData := WebhookData{user, repo, keypub, keypriv, g.webhookSecret}
whData := WebhookData{user, repo, multiweb, keypub, keypriv, g.webhookSecret}
jsonData, err := json.Marshal(whData)
if err != nil && err.Error() != "<nil>" {
log.Printf("Error marshaling data for webhook.")
@ -34,7 +35,7 @@ func (g *Gitea) WebhookDeploy(user, repo, keypriv, keypub string) error {
return err
}
if resp.StatusCode < 200 || resp.StatusCode > 299 {
// webhook listener must responses 400 if trigger rule (webhooksecret) is not satisfied
// webhook listener must response 400 if trigger rule (webhooksecret) is not satisfied
if resp.StatusCode == 400 {
return fmt.Errorf("Auth fail: %d", resp.StatusCode)
} else {

172
server/gitea.go

@ -8,84 +8,158 @@ import (
func (s *server) giteaHandler(w http.ResponseWriter, r *http.Request) {
response := s.newResponse("gitea", w, r)
// check permission for showing page
if response.Shell == "/bin/false" {
log.Printf("User %s doesn't have shell, can't access gitea", response.User)
log.Printf("Web deploy module: User %s doesn't have shell, can't access gitea", response.User)
response := s.newResponse("403", w, r)
response.execute(nil)
return
}
// first load
if r.Method != "POST" {
response.execute("")
return
}
usergitea := response.User
reponame := r.FormValue("reponame")
repo, err := s.gitea.Repo(usergitea, reponame)
if err != nil {
response.execute("ErrorGiteaInit")
log.Printf("Error loading the repo: %v", err)
return
// data for html template
type template_data struct {
ExitStatus string
RepoName string
}
// clean existing repo
if repo.Exists() {
if err := repo.Delete(); err != nil {
log.Printf("Error deleting gitea repo: %v ", err)
response.execute("Error")
return
}
data:= template_data{
ExitStatus: "",
RepoName: "",
}
// create repo from template repo
if err := repo.Migrate(); err != nil {
log.Printf("Error migrating template repo: %v", err)
response.execute("Error")
// init vars
usergitea:= response.User
reponame:= r.FormValue("reponame")
folder:= r.FormValue("folder") // "userfolder" or "usersubfolder"
mode := r.FormValue("mode") // "creterepo" or "setfolder"
keypub := ""
keypriv := ""
// check form (TODO: js)
if len(reponame) == 0 {
data.ExitStatus = "err_repo_empty"
response.execute(data)
return
}
// generate keys
keypriv, keypub, err := gitea.GenerateRSAKeyPair(4096)
// init repo object (config vars)
repo, err := s.gitea.Repo(usergitea, reponame)
if err != nil {
log.Printf("Error generating key pair: %v", err)
if err := repo.Delete(); err != nil {
log.Printf("Error deleting gitea repo: %v", err)
}
response.execute("Error")
log.Printf("Web deploy module: Error loading config for gitea functionality: %v", err)
data.ExitStatus = "err_lowry_config"
response.execute(data)
return
}
// create deploy key on repo
if err = repo.DeployKey(keypub); err != nil {
log.Printf("Error deploying key on gitea repo: %v", err)
if err := repo.Delete(); err != nil {
log.Printf("Error deleting gitea repo: %v", err)
}
response.execute("Error")
// check user exists, and return uid.
uid, err := repo.UserID()
if err != nil {
// connection error?
data.ExitStatus = "err_gitea_connection"
response.execute(data)
return
}
if uid == -2 {
log.Printf("Web deploy module: User doesn't exist on gitea.")
data.ExitStatus = "err_gitea_user"
response.execute(data)
return
}
// GITEA TASKS (if create is selected)
if mode == "createrepo" {
// create gitea webhook on repo
if err = repo.CreateWebhook(); err != nil {
log.Printf("Error creating webhook on gitea repo: %v", err)
if err := repo.Delete(); err != nil {
log.Printf("Error deleting gitea repo: %v", err)
// clean existing repo
if repo.Exists() {
if err := repo.Delete(); err != nil {
log.Printf("Web deploy module: Return, repo is empty.")
data.ExitStatus = "err_gitea_connection"
response.execute(data)
return
}
}
response.execute("Error")
return
// create repo from template repo
if err = repo.Migrate(); err != nil {
log.Printf("Web deploy module: Error migrating (copying) template repository: %v", err)
data.ExitStatus = "err_gitea_connection"
response.execute(data)
return
}
// generate keys
keypriv, keypub, err = gitea.GenerateRSAKeyPair(4096)
if err != nil {
log.Printf("Web deploy module: Error generating key pair: %v", err)
if err := repo.Delete(); err != nil {
log.Printf("Web deploy module: Error deleting gitea repository: %v", err)
}
data.ExitStatus = "err_gitea_connection"
response.execute(data)
return
}
// create deploy keys on repo
if err = repo.DeployKey(keypub); err != nil {
log.Printf("Web deploy module: Error deploying key on gitea repository: %v", err)
if err := repo.Delete(); err != nil {
log.Printf("Web deploy module: Error deleting gitea repository: %v", err)
}
data.ExitStatus = "err_gitea_connection"
response.execute(data)
return
}
// create gitea webhook on repo
if err = repo.CreateWebhook(); err != nil {
log.Printf("Web deploy module: Error creating webhook on repository: %v", err)
if err := repo.Delete(); err != nil {
log.Printf("Web deploy module: Error deleting repository: %v", err)
}
data.ExitStatus = "err_gitea_connection"
response.execute(data)
return
}
// gitea tasks completed
log.Printf("Web deploy module: Repo created, keys added, webhook added.")
data.ExitStatus = "repocreated-" + folder
} else if mode == "setfolder" {
if !repo.Exists() {
data.ExitStatus = "repo-nonexistent"
response.execute(data)
return
} else {
data.ExitStatus = folder
}
}
// send keys to web host via webhook.
if err = s.gitea.WebhookDeploy(usergitea, reponame, keypriv, keypub); err != nil {
log.Printf("Error passing keys to webserver host: %v", err)
if err = repo.Delete(); err != nil {
log.Printf("Error deleting gitea repo: %v", err)
log.Printf("Web deploy module: Set %s", folder)
// WEB HOST TASKS - send keys and set folder option via webhook.
if err = s.gitea.WebhookDeploy(usergitea, reponame, data.ExitStatus, keypriv, keypub); err != nil {
log.Printf("Web deploy module: Error, web host unreachable: %v", err)
if err := repo.Delete(); err != nil {
log.Printf("Web deploy module: Error deleting repository: %v", err)
}
response.execute("Error")
data.ExitStatus = "err_webhook_connection"
response.execute(data)
return
}
log.Printf("Gitea repo deployed and keys sent to webhook listener.")
response.execute("RepoDeployed")
// Success: return reponame
data.RepoName = reponame
// success
log.Printf("Web deploy module: keys and/or folder option was send to web host.")
log.Printf("Web deploy module: Done!")
response.execute(data)
}

144
tmpl/gitea.html

@ -2,41 +2,115 @@
{{template "header_close.html"}}
{{template "navbar.html" .}}
<div class="container">
<br />
<h1 class="row justify-content-center">Crear repositorio web</h1>
<br />
{{if eq .Data "RepoDeployed"}}
<br />
<br />
<h2 class="row justify-content-center">El repositorio se ha creado en tu cuenta de gitea</h2>
<div class="col-sm-4" style="margin: 0 auto; width: 100%">
<p class="row justify-content-center">Puedes acceder en:&nbsp;<a href="https://git.sindominio.net">https://git.sindominio.net</a></p>
<p class="row" style="text-align: justify;">Sólo tienes que editar un fichero en ese repositorio para activar una web estática en tu carpeta de usuario en /public_html/. Si lo haces, todo el contenido en esa carpeta será sustituido por un blog estático generado con hugo.</p>
</div>
{{else if eq .Data "ErrorGiteaInit"}}
<p class="row justify-content-center">Parece que la funcionalidad no está activada. Contacta con mi dominio.</p>
{{else if eq .Data "Error"}}
<div class="" style="color: #dc3545; text-align: center;">Algo salió mal. Contacta con sindominio.</div>
{{else}}
<br />
<div class="col-sm-4" style="margin: 0 auto; width: 100%">
<p class="row justify-content-center" style="text-align: justify;">Sindominio te ofrece un espacio web para contenidos estáticos. Puedes gestionarlo a través de un repositorio git, editando con nuestra interfaz web gitea.</p>
{{ $webURL := "https://sindominio.net" }}
{{ $giteaURL := "https://git.sindominio.net" }}
{{ $repoButton := true }}
{{ $err_msg := "" }}
{{ $err_description := "" }}
<div class="container">
<div class="col-xs-12 col-md-9 col-lg-6" style="margin: 3em auto;">
{{ if not .Data }}
<h1 class="row justify-content-center" >Crear repositorio web</h1>
</br>
<p class="row justify-content-center" style="text-align: justify;">
Desde aquí puedes crear un repositorio git que incluye un sitio hugo. Cada edición del repositorio reconstruye una web estática que se despliega automáticamente en tu espacio web en {{ $webURL }}/{{ .User }}.<br>
</p>
<div class="row justify-content-center">
<form class="" action="/gitea/" method="post" novalidate>
<div class="form-group">
<label for="reponame">Nombre del repo</label>
<input type="" id="reponame" name="reponame" placeholder="Nombre del repositorio">
</div>
<div class="form-group" style="margin-bottom: 2em;">
<p>La web se desplegará en:</p>
<input type="radio" id="userfolder" name="folder" value="userfolder" checked="checked">
<label for="userfolder">{{ $webURL }}/{{ .User }}/</label><br>
<input type="radio" id="usersubfolder" name="folder" value="usersubfolder">
<label for="usersubfolder">{{ $webURL}}/{{ .User }}/nombre_del_repo/</label><br>
</div>
<div style="display: flex; justify-content: center;">
<button class="btn btn-primary" type="submit" class="btn btn-primary justify-content-center" style="width:80%;" name="mode" value="createrepo">Crear repositorio y desplegar web</button>
</div>
<p class="row justify-content-center" style="font-size:0.9em; margin-top:10px;"><span style="color:red;"> ¡ATENCIÓN!&nbsp; </span><i>Si el repo ya existe será sobreescrito.</i><p>
<div style="display: flex; justify-content: center;">
<button class="btn btn-primary" type="submit" class="btn btn-primary justify-content-center" style="width:80%;" name="mode" value="setfolder">Sólo desplegar web</button>
</div>
<p class="row justify-content-center" style="font-size:0.9em; margin-top:10px;"><i>No se creará/borrará el repositorio, sólo se desplegará la web en la opción seleccionada.</i><p>
</form>
</div>
{{ else }}
<h3 class="" style="text-align: center;">
{{ if eq .Data.ExitStatus "err_repo_empty" }}
No has definido el repo en el formulario.
{{ else if eq .Data.ExitStatus "repo-nonexistent" }}
El repo no existe en gitea, quizás lo borraste o nunca lo has creado.
{{ else if eq .Data.ExitStatus "repocreated-userfolder" }}
El repositorio se ha creado en tu cuenta de gitea.
{{ else if eq .Data.ExitStatus "repocreated-usersubfolder" }}
El repositorio se ha creado en tu cuenta de gitea, y se desplegará en subcarpeta web.
{{ else if eq .Data.ExitStatus "userfolder" }}
Modo subcarpeta desactivado.
{{ else if eq .Data.ExitStatus "usersubfolder" }}
Modo subcarpeta activado.
{{ else if eq .Data.ExitStatus "err_gitea_connection" }}
Error: no se puede conectar al servidor git.
{{ else if eq .Data.ExitStatus "err_gitea_user" }}
Error: tu cuenta no existe en el gestor de repositorios. Logueate allí primero y vuelve a intentarlo.
{{ else if eq .Data.ExitStatus "err_webhook_connection" }}
Error: El host web no responde o lowry no puede acreditarse allí.
{{ else }}
Algo salió mal.
{{ end }}
</h3>
{{ if .Data.RepoName }}
<div style="margin-top: 2em;">
<p style='text-align: center;'>
Puedes acceder al repositorio con tus credenciales y editarlo.<br>
<a href="{{ $giteaURL }}/{{ .User }}/{{ .Data.RepoName }}">{{ $giteaURL }}/{{ .User }}/{{ .Data.RepoName }}</a>
</p>
<p style='text-align: center;'>
La web la puedes ver en:<br>
<a href="{{ $webURL }}/{{ .User }}/{{ if or (eq .Data.ExitStatus "repocreated-usersubfolder") (eq .Data.ExitStatus "usersubfolder") }}{{ .Data.RepoName }}/{{ end }}">{{ $webURL }}/{{ .User }}/{{ if or (eq .Data.ExitStatus "repocreated-usersubfolder") (eq .Data.ExitStatus "usersubfolder") }}{{ .Data.RepoName }}/{{ end }}</a>
</p>
<p style='text-align: center;'>
Puedes añadir (o modificar) contenido a tu web incluyendo tus textos en ficheros dentro de la carpeta content/post/ del repositorio. Tienes más información para empezar a usar tu web en los enlaces de ayuda.
</p>
</div>
{{ end }}
<div class="box flex justify-content-center" style="display: flex; margin-top: 2em;">
<div class="" style="color:#fff; background-color: #007BFF;border-radius:0.25rem; margin-left:4px;">
<a href="/gitea/" style="text-align: center; color:#FFF; display: block; padding: 1em;">VOLVER</a>
</div>
{{ if .Data.RepoName }}
<div class="" style="color:#fff; background-color: #007BFF;border-radius:0.25rem; margin-left:4px;">
<a href="{{ $giteaURL }}/{{ .User }}" style="text-align: center; color:#FFF; display: block; padding: 1em;">REPOSITORIOS</a>
</div>
{{ end }}
{{ if or (.Data.RepoName) (eq .Data.ExitStatus "err_gitea_user") }}
<div class="" style="color:#fff; background-color: #007BFF;border-radius:0.25rem; margin-left:4px;">
<a href="{{ $webURL }}/{{ .User }}/{{ if or (eq .Data.ExitStatus "repocreated-usersubfolder") (eq .Data.ExitStatus "usersubfolder") }}{{ .Data.RepoName }}/{{ end }}" style="text-align: center; color:#FFF; display: block; padding: 1em;">WEB</a>
</div>
{{ end }}
</div>
<div class="row justify-content-center">
<form class="col-sm-4" id="needs-validation" action="/gitea/" method="post" novalidate>
<div class="form-group">
<label for="reponame">Nombre del repo</label>
<input type="" id="reponame" name="reponame" placeholder="Nombre del repositorio">
</div>
<button id="creategitea" type="submit" class="btn btn-primary justify-content-center" style="width:100%;">Crear</button>
<br />
<div class="form-group">
<p class="row justify-content-center" style="font-size:0.9em; margin-top:10px;"><span style="color:red;"> ¡ATENCIÓN!&nbsp; </span><i>Si el repo ya existe será sobreescrito.</i><p>
</div>
</form>
</div>
{{end}}
</div>
{{ end }}
<hr style="border-top:2px solid #ccc; margin: 2em 0;">
<p>AYUDAS:</p>
<ul>
<li><a href="https://sindominio.net/trastienda/manuales/web_git/">Webs estáticas con git en sindominio</a></li>
<li><a href="https://sindominio.net/trastienda/manuales/conectar_home/">Cómo conectar a mi home (ssh, sftp)</a></li>
<li><a href="https://sindominio.net/trastienda/manuales/markdown_intro/">Markdown</a>.</li>
</ul>
</div> <!-- end col-sm -->
</div> <!--end container -->
{{template "footer.html"}}

2
tmpl/index.html

@ -47,7 +47,7 @@
<li class="list-group-item"><a href="/adduser/">Invitar amiga a SinDominio</a></li>
{{end}}
{{if ne .Shell "/bin/false"}}
<li class="list-group-item"><a href="/gitea/">Crear repositorio web</a></li>
<li class="list-group-item"><a href="/gitea/">Gestionar repositorio web</a></li>
{{end}}
{{if .IsAdmin}}
<li class="list-group-item"><a href="/users/">Ver listado de cuentas</a></li>

Loading…
Cancel
Save