diff options
-rw-r--r-- | garage.go | 53 | ||||
-rw-r--r-- | main.go | 1 | ||||
-rw-r--r-- | templates/garage_website_edit.html | 72 | ||||
-rw-r--r-- | templates/garage_website_inspect.html | 2 | ||||
-rw-r--r-- | website.go | 17 |
5 files changed, 141 insertions, 4 deletions
@@ -270,8 +270,9 @@ func handleWebsiteInspect(w http.ResponseWriter, r *http.Request) { _, processErr = ctrl.Patch(bucketName, &WebsitePatch{Size: &user.Quota.WebsiteSizeBursted}) case "delete_bucket": processErr = ctrl.Delete(bucketName) - http.Redirect(w, r, "/website", http.StatusFound) - return + if processErr == nil { + http.Redirect(w, r, "/website", http.StatusFound) + } default: processErr = fmt.Errorf("Unknown action") } @@ -295,3 +296,51 @@ func handleWebsiteInspect(w http.ResponseWriter, r *http.Request) { tWebsiteInspect := getTemplate("garage_website_inspect.html") tWebsiteInspect.Execute(w, &tpl) } + +func handleWebsiteVhost(w http.ResponseWriter, r *http.Request) { + var processErr error + + user := RequireUserHtml(w, r) + if user == nil { + return + } + + ctrl, err := NewWebsiteController(user) + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + + bucketName := mux.Vars(r)["bucket"] + + if r.Method == "POST" { + r.ParseForm() + + bucket := strings.Join(r.Form["bucket"], "") + if bucket == "" { + bucket = strings.Join(r.Form["bucket2"], "") + } + + view, processErr := ctrl.Patch(bucketName, &WebsitePatch{Vhost: &bucket}) + if processErr == nil { + http.Redirect(w, r, "/website/inspect/"+view.Name.Pretty, http.StatusFound) + return + } + } + + view, err := ctrl.Inspect(bucketName) + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + + describe, err := ctrl.Describe() + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + + tpl := &WebsiteInspectTpl{describe, view, processErr} + tWebsiteEdit := getTemplate("garage_website_edit.html") + tWebsiteEdit.Execute(w, &tpl) +} @@ -161,6 +161,7 @@ func server(args []string) { r.HandleFunc("/website/new", handleWebsiteNew) r.HandleFunc("/website/configure", handleWebsiteConfigure) r.HandleFunc("/website/inspect/{bucket}", handleWebsiteInspect) + r.HandleFunc("/website/vhost/{bucket}", handleWebsiteVhost) r.HandleFunc("/invite/new_account", handleInviteNewAccount) r.HandleFunc("/invite/send_code", handleInviteSendCode) diff --git a/templates/garage_website_edit.html b/templates/garage_website_edit.html new file mode 100644 index 0000000..f41d30b --- /dev/null +++ b/templates/garage_website_edit.html @@ -0,0 +1,72 @@ +{{define "title"}}Créer un site web |{{end}} + +{{define "body"}} +<div class="d-flex"> + <h4>Modifier le nom de domaine</h4> + <a class="ml-auto btn btn-link" href="/website/configure">Mes identifiants</a> + <a class="ml-4 btn btn-info" href="/website">Mes sites webs</a> +</div> + +<div class="row mt-3"> + <div class="col-md-12"> + {{if .Err}} + <div class="alert alert-danger">{{ .Err.Error }}</div> + {{end}} + </div> +</div> + +<ul class="nav nav-tabs" id="proto" role="tablist"> + <li class="nav-item"> + <a class="nav-link active" id="dnsint-tab" data-toggle="tab" href="#dnsint" role="tab" aria-controls="dnsint" aria-selected="true">Je n'ai pas de nom de domaine</a> + </li> + <li class="nav-item"> + <a class="nav-link" id="dnsext-tab" data-toggle="tab" href="#dnsext" role="tab" aria-controls="dnsext" aria-selected="false">Utiliser mon propre nom de domaine</a> + </li> +</ul> + +<div class="tab-content" id="protocols"> + + <div class="tab-pane fade show active" id="dnsint" role="tabpanel" aria-labelledby="dnsint-tab"> + <form method="POST" class="mt-4"> + <div class="form-row"> + <div class="form-group col-md-6"> + <label for="bucket">Sous-domaine désiré :</label> + <input type="text" id="bucket" name="bucket" placeholder="mon-site" class="form-control" value="" onkeyup="document.getElementById('url').value = `https://${document.getElementById('bucket').value}.web.deuxfleurs.fr`" /> + </div> + <div class="form-group col-md-6"> + <label for="url">Votre site sera accessible à l'URL suivante :</label> + <input type="text" id="url" disabled="true" name="url" class="form-control" value="https://mon-site.web.deuxfleurs.fr" /> + </div> + </div> + <div class="mt-4"> + <p>La première fois que vous chargerez votre site web, une erreur de certificat sera renvoyée. C'est normal, il faudra patienter quelques minutes le temps que le certificat se génère.</p> + </div> + <button type="submit" class="btn btn-primary">Modifier le nom de domaine</button> + </form> + </div> + <div class="tab-pane fade show" id="dnsext" role="tabpanel" aria-labelledby="dnsext-tab"> + <form method="POST" class="mt-4"> + <div class="form-row"> + <div class="form-group col-md-6"> + <label for="bucket2">Votre nom de domaine :</label> + <input type="text" id="bucket2" name="bucket2" placeholder="example.com" class="form-control" value="" onkeyup="document.getElementById('url2').value = `https://${document.getElementById('bucket2').value}`" /> + </div> + <div class="form-group col-md-6"> + <label for="url2">Votre site sera accessible à l'URL suivante :</label> + <input type="text" id="url2" disabled="true" name="url2" class="form-control" value="https://example.com" /> + </div> + </div> + <div> + <p>Vous devez éditer votre zone DNS, souvent gérée par votre bureau d'enregistrement, comme Gandi, pour la faire pointer vers Deuxfleurs. Si vous utilisez un sous domaine (eg. <code>site.example.com</code>), une entrée <code>CNAME</code> est appropriée :</p> + <pre>site CNAME 3600 garage.deuxfleurs.fr.</pre> + <p>Si vous utilisez la racine de votre nom de domaine (eg. <code>example.com</code>, aussi appelée APEX), la solution dépend de votre fournisseur DNS, il vous faudra au choix une entrée <code>ALIAS</code> ou <code>CNAME</code> en fonction de ce que votre fournisseur supporte :</p> + <pre>@ ALIAS 3600 garage.deuxfleurs.fr.</pre> + <p>La première fois que vous chargerez votre site web, une erreur de certificat sera renvoyée. C'est normal, il faudra patienter quelques minutes le temps que le certificat se génère.</p> + </div> + <div class="mt-4"> + <button type="submit" class="btn btn-primary">Modifier le nom de domaine</button> + </form> + + </div> +</div> +{{end}} diff --git a/templates/garage_website_inspect.html b/templates/garage_website_inspect.html index c047b18..a8f463d 100644 --- a/templates/garage_website_inspect.html +++ b/templates/garage_website_inspect.html @@ -63,7 +63,7 @@ <form action="" method="post"> <div class="btn-group" role="group" aria-label="Actions sur le site web"> <button class="btn btn-secondary" name="action" value="increase_quota">Augmenter le quota</button> - <a class="btn btn-secondary disabled">Changer le nom de domaine</a> + <a class="btn btn-secondary" href="/website/vhost/{{ .View.Name.Pretty }}">Changer le nom de domaine</a> <button class="btn btn-danger" name="action" value="delete_bucket">Supprimer</button> </div> </form> @@ -17,6 +17,8 @@ var ( ErrCantConfigureBucket = fmt.Errorf("Unable to configure the bucket (activating website, adding quotas, etc.)") ErrBucketDeleteNotEmpty = fmt.Errorf("You must remove all the files before deleting a bucket") ErrBucketDeleteUnfinishedUpload = fmt.Errorf("You must remove all the unfinished multipart uploads before deleting a bucket") + ErrCantChangeVhost = fmt.Errorf("Can't change the vhost to the desired value. Maybe it's already used by someone else or an internal error occured") + ErrCantRemoveOldVhost = fmt.Errorf("The new vhost is bound to the bucket but the old one can't be removed, this is an internal error") ) type WebsiteId struct { @@ -141,12 +143,24 @@ func (w *WebsiteController) Patch(pretty string, patch *WebsitePatch) (*WebsiteV ur := garage.NewUpdateBucketRequest() ur.SetQuotas(*urQuota) - // Call garage + // Call garage "update bucket" function binfo, err = grgUpdateBucket(website.Internal, ur) if err != nil { return nil, ErrCantConfigureBucket } + // Update the alias if the vhost field is set and different + if patch.Vhost != nil && *patch.Vhost != "" && *patch.Vhost != pretty { + binfo, err = grgAddGlobalAlias(website.Internal, *patch.Vhost) + if err != nil { + return nil, ErrCantChangeVhost + } + binfo, err = grgDelGlobalAlias(website.Internal, pretty) + if err != nil { + return nil, ErrCantRemoveOldVhost + } + } + return NewWebsiteView(binfo), nil } @@ -233,4 +247,5 @@ func NewWebsiteView(binfo *garage.BucketInfo) *WebsiteView { type WebsitePatch struct { Size *int64 `json:"quota_size"` + Vhost *string `json:"vhost"` } |