aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorQuentin <quentin@dufour.io>2023-10-17 16:34:13 +0000
committerQuentin <quentin@dufour.io>2023-10-17 16:34:13 +0000
commit51a5771b0ba94efd35e0828c8423bc525ac8933f (patch)
tree52c2418e31f564469ac0f7e06589a198b5f094b3
parent10bdee10cf6947ec6dd0ba5040d7274d6c3316a7 (diff)
parent4f7cbdd8252f0064729f22929c7ca0e63a10d284 (diff)
downloadguichet-51a5771b0ba94efd35e0828c8423bc525ac8933f.tar.gz
guichet-51a5771b0ba94efd35e0828c8423bc525ac8933f.zip
Merge pull request 'change-vhost' (#47) from change-vhost into main
Reviewed-on: https://git.deuxfleurs.fr/Deuxfleurs/guichet/pulls/47
-rw-r--r--garage.go53
-rw-r--r--main.go1
-rw-r--r--templates/garage_website_edit.html72
-rw-r--r--templates/garage_website_inspect.html4
-rw-r--r--website.go17
5 files changed, 142 insertions, 5 deletions
diff --git a/garage.go b/garage.go
index c43fd5f..7cd879b 100644
--- a/garage.go
+++ b/garage.go
@@ -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)
+}
diff --git a/main.go b/main.go
index 6553bef..39c7f08 100644
--- a/main.go
+++ b/main.go
@@ -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 37142df..a8f463d 100644
--- a/templates/garage_website_inspect.html
+++ b/templates/garage_website_inspect.html
@@ -48,7 +48,7 @@
<h5 class="mt-3">Quotas</h5>
<div class="progress mt-3">
<div class="progress-bar" role="progressbar" aria-valuenow="{{ .View.Size.Current }}" aria-valuemin="0" aria-valuemax="{{ .View.Size.Max }}" style="width: {{ .View.Size.Percent }}%; min-width: 2em;">
- {{ .View.Size.Ratio }}%
+ {{ .View.Size.Percent }}%
</div>
</div>
@@ -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>
diff --git a/website.go b/website.go
index 2cad12c..74daf89 100644
--- a/website.go
+++ b/website.go
@@ -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"`
}