don't display the global key anymore
This commit is contained in:
parent
793cb2d3c2
commit
9cd06c95eb
7 changed files with 223 additions and 432 deletions
181
garage.go
181
garage.go
|
@ -4,10 +4,7 @@ import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
garage "git.deuxfleurs.fr/garage-sdk/garage-admin-sdk-golang"
|
garage "git.deuxfleurs.fr/garage-sdk/garage-admin-sdk-golang"
|
||||||
"github.com/gorilla/mux"
|
|
||||||
"log"
|
"log"
|
||||||
"net/http"
|
|
||||||
"strings"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func gadmin() (*garage.APIClient, context.Context) {
|
func gadmin() (*garage.APIClient, context.Context) {
|
||||||
|
@ -166,181 +163,3 @@ func grgDeleteBucket(bid string) error {
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- Start page rendering functions
|
|
||||||
|
|
||||||
func handleWebsiteConfigure(w http.ResponseWriter, r *http.Request) {
|
|
||||||
user := RequireUserHtml(w, r)
|
|
||||||
if user == nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
tKey := getTemplate("garage_key.html")
|
|
||||||
tKey.Execute(w, user)
|
|
||||||
}
|
|
||||||
|
|
||||||
func handleWebsiteList(w http.ResponseWriter, r *http.Request) {
|
|
||||||
user := RequireUserHtml(w, r)
|
|
||||||
if user == nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
ctrl, err := NewWebsiteController(user)
|
|
||||||
if err != nil {
|
|
||||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(ctrl.PrettyList) > 0 {
|
|
||||||
http.Redirect(w, r, "/website/inspect/"+ctrl.PrettyList[0], http.StatusFound)
|
|
||||||
} else {
|
|
||||||
http.Redirect(w, r, "/website/new", http.StatusFound)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
type WebsiteNewTpl struct {
|
|
||||||
Ctrl *WebsiteController
|
|
||||||
Err error
|
|
||||||
}
|
|
||||||
|
|
||||||
func handleWebsiteNew(w http.ResponseWriter, r *http.Request) {
|
|
||||||
user := RequireUserHtml(w, r)
|
|
||||||
if user == nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
ctrl, err := NewWebsiteController(user)
|
|
||||||
if err != nil {
|
|
||||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
tpl := &WebsiteNewTpl{ctrl, nil}
|
|
||||||
|
|
||||||
tWebsiteNew := getTemplate("garage_website_new.html")
|
|
||||||
if r.Method == "POST" {
|
|
||||||
r.ParseForm()
|
|
||||||
|
|
||||||
bucket := strings.Join(r.Form["bucket"], "")
|
|
||||||
if bucket == "" {
|
|
||||||
bucket = strings.Join(r.Form["bucket2"], "")
|
|
||||||
}
|
|
||||||
|
|
||||||
view, err := ctrl.Create(bucket)
|
|
||||||
if err != nil {
|
|
||||||
tpl.Err = err
|
|
||||||
tWebsiteNew.Execute(w, tpl)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
http.Redirect(w, r, "/website/inspect/"+view.Name.Pretty, http.StatusFound)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
tWebsiteNew.Execute(w, tpl)
|
|
||||||
}
|
|
||||||
|
|
||||||
type WebsiteInspectTpl struct {
|
|
||||||
Describe *WebsiteDescribe
|
|
||||||
View *WebsiteView
|
|
||||||
Err error
|
|
||||||
}
|
|
||||||
|
|
||||||
func handleWebsiteInspect(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()
|
|
||||||
action := strings.Join(r.Form["action"], "")
|
|
||||||
switch action {
|
|
||||||
case "increase_quota":
|
|
||||||
_, processErr = ctrl.Patch(bucketName, &WebsitePatch{Size: &user.Quota.WebsiteSizeBursted})
|
|
||||||
case "delete_bucket":
|
|
||||||
processErr = ctrl.Delete(bucketName)
|
|
||||||
if processErr == nil {
|
|
||||||
http.Redirect(w, r, "/website", http.StatusFound)
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
processErr = fmt.Errorf("Unknown action")
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
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}
|
|
||||||
|
|
||||||
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)
|
|
||||||
}
|
|
||||||
|
|
1
main.go
1
main.go
|
@ -159,7 +159,6 @@ func server(args []string) {
|
||||||
|
|
||||||
r.HandleFunc("/website", handleWebsiteList)
|
r.HandleFunc("/website", handleWebsiteList)
|
||||||
r.HandleFunc("/website/new", handleWebsiteNew)
|
r.HandleFunc("/website/new", handleWebsiteNew)
|
||||||
r.HandleFunc("/website/configure", handleWebsiteConfigure)
|
|
||||||
r.HandleFunc("/website/inspect/{bucket}", handleWebsiteInspect)
|
r.HandleFunc("/website/inspect/{bucket}", handleWebsiteInspect)
|
||||||
r.HandleFunc("/website/vhost/{bucket}", handleWebsiteVhost)
|
r.HandleFunc("/website/vhost/{bucket}", handleWebsiteVhost)
|
||||||
|
|
||||||
|
|
|
@ -1,234 +0,0 @@
|
||||||
{{define "title"}}Profile |{{end}}
|
|
||||||
|
|
||||||
{{define "body"}}
|
|
||||||
<div class="d-flex">
|
|
||||||
<h4>Mes identifiants</h4>
|
|
||||||
<a class="ml-auto btn btn-link" href="/website">Mes sites webs</a>
|
|
||||||
<a class="ml-4 btn btn-info" href="/">Menu principal</a>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<ul class="nav nav-tabs" id="proto" role="tablist">
|
|
||||||
<li class="nav-item">
|
|
||||||
<a class="nav-link active" id="s3-tab" data-toggle="tab" href="#s3" role="tab" aria-controls="s3" aria-selected="true">S3</a>
|
|
||||||
</li>
|
|
||||||
<li class="nav-item">
|
|
||||||
<a class="nav-link" id="sftp-tab" data-toggle="tab" href="#sftp" role="tab" aria-controls="sftp" aria-selected="false">SFTP</a>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
<div class="tab-content" id="protocols">
|
|
||||||
<div class="tab-pane fade show active" id="s3" role="tabpanel" aria-labelledby="s3-tab">
|
|
||||||
<table class="table mt-4">
|
|
||||||
<tbody>
|
|
||||||
<tr>
|
|
||||||
<th scope="row" class="col-md-2">Identifiant de clé</th>
|
|
||||||
<td>{{ .S3KeyInfo.AccessKeyId }}</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<th scope="row">Clé secrète</th>
|
|
||||||
<td><a href="#" onclick="document.getElementById('secret_key').style.display='inline'; this.style.display='none'">Cliquer pour afficher la clé secrète</a><span id="secret_key" style="display: none">{{ .S3KeyInfo.SecretAccessKey }}</span></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<th scope="row">Région</th>
|
|
||||||
<td>garage</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<th scope="row">Endpoint URL</th>
|
|
||||||
<td>https://garage.deuxfleurs.fr</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<th scope="row">Type d'URL</th>
|
|
||||||
<td>DNS et chemin (préférer chemin)</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<th scope="row">Signature</th>
|
|
||||||
<td>Version 4</td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
<p>Configurer votre logiciel :</p>
|
|
||||||
|
|
||||||
<div class="accordion" id="softconfig">
|
|
||||||
<div class="card">
|
|
||||||
<div class="card-header" id="awscli-title">
|
|
||||||
<h2 class="mb-0">
|
|
||||||
<button class="btn btn-link btn-block text-left collapsed" type="button" data-toggle="collapse" data-target="#awscli" aria-expanded="false" aria-controls="awscli">
|
|
||||||
awscli
|
|
||||||
</button>
|
|
||||||
</h2>
|
|
||||||
</div>
|
|
||||||
<div id="awscli" class="collapse" aria-labelledby="awscli-title" data-parent="#softconfig">
|
|
||||||
<div class="card-body">
|
|
||||||
<p>Créez un fichier nommé <code>~/.awsrc</code> :</p>
|
|
||||||
<pre>
|
|
||||||
export AWS_ACCESS_KEY_ID={{ .S3KeyInfo.AccessKeyId }}
|
|
||||||
export AWS_SECRET_ACCESS_KEY={{ .S3KeyInfo.SecretAccessKey }}
|
|
||||||
export AWS_DEFAULT_REGION='garage'
|
|
||||||
|
|
||||||
function aws { command aws --endpoint-url https://garage.deuxfleurs.fr $@ ; }
|
|
||||||
aws --version
|
|
||||||
</pre>
|
|
||||||
<p>Ensuite vous pouvez utiliser awscli :</p>
|
|
||||||
<pre>
|
|
||||||
source ~/.awsrc
|
|
||||||
aws s3 ls
|
|
||||||
aws s3 ls s3://my-bucket
|
|
||||||
aws s3 cp /tmp/a.txt s3://my-bucket
|
|
||||||
...
|
|
||||||
</pre>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="card">
|
|
||||||
<div class="card-header" id="minio-title">
|
|
||||||
<h2 class="mb-0">
|
|
||||||
<button class="btn btn-link btn-block text-left" type="button" data-toggle="collapse" data-target="#minio" aria-expanded="true" aria-controls="minio">
|
|
||||||
Minio CLI
|
|
||||||
</button>
|
|
||||||
</h2>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div id="minio" class="collapse" aria-labelledby="minio-title" data-parent="#softconfig">
|
|
||||||
<div class="card-body">
|
|
||||||
<p>Vous pouvez configurer Minio CLI avec cette commande :</p>
|
|
||||||
<pre>
|
|
||||||
mc alias set \
|
|
||||||
garage \
|
|
||||||
https://garage.deuxfleurs.fr \
|
|
||||||
{{ .S3KeyInfo.AccessKeyId }} \
|
|
||||||
{{ .S3KeyInfo.SecretAccessKey }} \
|
|
||||||
--api S3v4
|
|
||||||
</pre>
|
|
||||||
<p>Et ensuite pour utiliser Minio CLI avec :</p>
|
|
||||||
<pre>
|
|
||||||
mc ls garage/
|
|
||||||
mc cp /tmp/a.txt garage/my-bucket/a.txt
|
|
||||||
...
|
|
||||||
</pre>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="card">
|
|
||||||
<div class="card-header" id="winscp-title">
|
|
||||||
<h2 class="mb-0">
|
|
||||||
<button class="btn btn-link btn-block text-left" type="button" data-toggle="collapse" data-target="#winscp" aria-expanded="true" aria-controls="winscp">
|
|
||||||
WinSCP
|
|
||||||
</button>
|
|
||||||
</h2>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div id="winscp" class="collapse" aria-labelledby="winscp-title" data-parent="#softconfig">
|
|
||||||
<div class="card-body">
|
|
||||||
Reportez vous <a href="">au guide</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="card">
|
|
||||||
<div class="card-header" id="hugo-title">
|
|
||||||
<h2 class="mb-0">
|
|
||||||
<button class="btn btn-link btn-block text-left collapsed" type="button" data-toggle="collapse" data-target="#hugo" aria-expanded="false" aria-controls="hugo">
|
|
||||||
Hugo
|
|
||||||
</button>
|
|
||||||
</h2>
|
|
||||||
</div>
|
|
||||||
<div id="hugo" class="collapse" aria-labelledby="hugo-title" data-parent="#softconfig">
|
|
||||||
<div class="card-body">
|
|
||||||
<p>Dans votre fichier <code>config.toml</code>, rajoutez :</p>
|
|
||||||
<pre>
|
|
||||||
[[deployment.targets]]
|
|
||||||
URL = "s3://bucket?endpoint=garage.deuxfleurs.fr&s3ForcePathStyle=true&region=garage"
|
|
||||||
</pre>
|
|
||||||
<p>Assurez-vous d'avoir un fichier dans lequel les variables <code>AWS_ACCESS_KEY_ID</code> et <code>AWS_SECRET_ACCESS_KEY</code> sont définies,
|
|
||||||
ici on suppose que vous avez suivi les instructions de l'outil awscli (ci-dessus) et que vous avez un fichier <code>~/.awsrc</code> qui défini ces variables.
|
|
||||||
Ensuite : </p>
|
|
||||||
<pre>
|
|
||||||
source ~/.awsrc
|
|
||||||
hugo deploy
|
|
||||||
</pre>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="card">
|
|
||||||
<div class="card-header" id="publii-title">
|
|
||||||
<h2 class="mb-0">
|
|
||||||
<button class="btn btn-link btn-block text-left collapsed" type="button" data-toggle="collapse" data-target="#publii" aria-expanded="false" aria-controls="publii">
|
|
||||||
Publii
|
|
||||||
</button>
|
|
||||||
</h2>
|
|
||||||
</div>
|
|
||||||
<div id="publii" class="collapse" aria-labelledby="publii-title" data-parent="#softconfig">
|
|
||||||
<div class="card-body">
|
|
||||||
<em>Bientôt...</em>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- sftp -->
|
|
||||||
<div class="tab-pane fade" id="sftp" role="tabpanel" aria-labelledby="sftp-tab">
|
|
||||||
<table class="table mt-4">
|
|
||||||
<tbody>
|
|
||||||
<tr>
|
|
||||||
<th scope="row">Nom d'utilisateur-ice</th>
|
|
||||||
<td>{{ .Login.Info.Username }}</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<th scope="row">Mot de passe</th>
|
|
||||||
<td>(votre mot de passe guichet)</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<th scope="row">Hôte</th>
|
|
||||||
<td>sftp://bagage.deuxfleurs.fr</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<th scope="row">Port</th>
|
|
||||||
<td>2222</td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
<p>Configurer votre logiciel :</p>
|
|
||||||
|
|
||||||
<div class="accordion" id="softconfig2">
|
|
||||||
<div class="card">
|
|
||||||
<div class="card-header" id="filezilla-title">
|
|
||||||
<h2 class="mb-0">
|
|
||||||
<button class="btn btn-link btn-block text-left collapsed" type="button" data-toggle="collapse" data-target="#filezilla" aria-expanded="false" aria-controls="filezilla">
|
|
||||||
scp
|
|
||||||
</button>
|
|
||||||
</h2>
|
|
||||||
</div>
|
|
||||||
<div id="filezilla" class="collapse show" aria-labelledby="filezilla-title" data-parent="#softconfig">
|
|
||||||
<div class="card-body">
|
|
||||||
<p>Un exemple avec SCP :</p>
|
|
||||||
<pre>
|
|
||||||
scp -oHostKeyAlgorithms=+ssh-rsa -P2222 -r ./public {{ .Login.Info.Username }}@bagage.deuxfleurs.fr:mon_bucket/
|
|
||||||
</pre>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="card">
|
|
||||||
<div class="card-header" id="filezilla-title">
|
|
||||||
<h2 class="mb-0">
|
|
||||||
<button class="btn btn-link btn-block text-left collapsed" type="button" data-toggle="collapse" data-target="#filezilla" aria-expanded="false" aria-controls="filezilla">
|
|
||||||
Filezilla
|
|
||||||
</button>
|
|
||||||
</h2>
|
|
||||||
</div>
|
|
||||||
<div id="filezilla" class="collapse" aria-labelledby="filezilla-title" data-parent="#softconfig">
|
|
||||||
<div class="card-body">
|
|
||||||
<em>Bientôt</em>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{{end}}
|
|
|
@ -59,10 +59,44 @@
|
||||||
{{ end }}
|
{{ end }}
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
<h5 class="mt-3">Informations de connexion</h5>
|
||||||
|
<table class="table mt-4">
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<th scope="row" class="col-md-2">Identifiant de clé</th>
|
||||||
|
<td>{{ .View.AccessKeyId }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th scope="row">Clé secrète</th>
|
||||||
|
<td>
|
||||||
|
<a href="#" onclick="document.getElementById('secret_key').style.display='inline'; this.style.display='none'">Cliquer pour afficher la clé secrète</a>
|
||||||
|
<span id="secret_key" style="display: none">{{ .View.SecretAccessKey }}</span>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th scope="row">Région</th>
|
||||||
|
<td>garage</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th scope="row">Endpoint URL</th>
|
||||||
|
<td>https://garage.deuxfleurs.fr</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th scope="row">Type d'URL</th>
|
||||||
|
<td>DNS et chemin (préférer chemin)</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th scope="row">Signature</th>
|
||||||
|
<td>Version 4</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
<h5 class="mt-3">Actions</h5>
|
<h5 class="mt-3">Actions</h5>
|
||||||
<form action="" method="post">
|
<form action="" method="post">
|
||||||
<div class="btn-group" role="group" aria-label="Actions sur le site web">
|
<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>
|
<button class="btn btn-secondary" name="action" value="increase_quota">Augmenter le quota</button>
|
||||||
|
<button class="btn btn-secondary" name="action" value="rotate_key">Rotation de la clé</button>
|
||||||
<a class="btn btn-secondary" href="/website/vhost/{{ .View.Name.Pretty }}">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>
|
<button class="btn btn-danger" name="action" value="delete_bucket">Supprimer</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -24,10 +24,9 @@
|
||||||
<div class="mt-3">
|
<div class="mt-3">
|
||||||
<div class="card">
|
<div class="card">
|
||||||
<div class="card-header">
|
<div class="card-header">
|
||||||
Mon espace sur la toile
|
Mes services
|
||||||
</div>
|
</div>
|
||||||
<div class="list-group list-group-flush">
|
<div class="list-group list-group-flush">
|
||||||
<a class="list-group-item list-group-item-action" href="/website/configure">Mes identifiants</a>
|
|
||||||
<a class="list-group-item list-group-item-action" href="/website">Mes sites Web</a>
|
<a class="list-group-item list-group-item-action" href="/website">Mes sites Web</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
19
website.go
19
website.go
|
@ -81,26 +81,17 @@ func NewWebsiteController(user *LoggedUser) (*WebsiteController, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
type WebsiteDescribe struct {
|
type WebsiteDescribe struct {
|
||||||
AccessKeyId string `json:"access_key_id"`
|
|
||||||
SecretAccessKey string `json:"secret_access_key"`
|
|
||||||
AllowedWebsites *QuotaStat `json:"quota_website_count"`
|
AllowedWebsites *QuotaStat `json:"quota_website_count"`
|
||||||
BurstBucketQuotaSize string `json:"burst_bucket_quota_size"`
|
BurstBucketQuotaSize string `json:"burst_bucket_quota_size"`
|
||||||
Websites []*WebsiteId `json:"vhosts"`
|
Websites []*WebsiteId `json:"vhosts"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *WebsiteController) Describe() (*WebsiteDescribe, error) {
|
func (w *WebsiteController) Describe() (*WebsiteDescribe, error) {
|
||||||
s3key, err := w.User.S3KeyInfo()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
r := make([]*WebsiteId, 0, len(w.PrettyList))
|
r := make([]*WebsiteId, 0, len(w.PrettyList))
|
||||||
for _, k := range w.PrettyList {
|
for _, k := range w.PrettyList {
|
||||||
r = append(r, w.WebsiteIdx[k])
|
r = append(r, w.WebsiteIdx[k])
|
||||||
}
|
}
|
||||||
return &WebsiteDescribe{
|
return &WebsiteDescribe{
|
||||||
*s3key.AccessKeyId,
|
|
||||||
*s3key.SecretAccessKey,
|
|
||||||
&w.WebsiteCount,
|
&w.WebsiteCount,
|
||||||
w.User.Quota.WebsiteSizeBurstedPretty(),
|
w.User.Quota.WebsiteSizeBurstedPretty(),
|
||||||
r}, nil
|
r}, nil
|
||||||
|
@ -232,6 +223,8 @@ func (w *WebsiteController) Delete(pretty string) error {
|
||||||
|
|
||||||
type WebsiteView struct {
|
type WebsiteView struct {
|
||||||
Name *WebsiteId `json:"vhost"`
|
Name *WebsiteId `json:"vhost"`
|
||||||
|
AccessKeyId string `json:"access_key_id"`
|
||||||
|
SecretAccessKey string `json:"secret_access_key"`
|
||||||
Size QuotaStat `json:"quota_size"`
|
Size QuotaStat `json:"quota_size"`
|
||||||
Files QuotaStat `json:"quota_files"`
|
Files QuotaStat `json:"quota_files"`
|
||||||
}
|
}
|
||||||
|
@ -242,7 +235,13 @@ func NewWebsiteView(binfo *garage.BucketInfo) *WebsiteView {
|
||||||
wid := NewWebsiteIdFromBucketInfo(binfo)
|
wid := NewWebsiteIdFromBucketInfo(binfo)
|
||||||
size := NewQuotaStat(*binfo.Bytes, (&q).GetMaxSize(), true)
|
size := NewQuotaStat(*binfo.Bytes, (&q).GetMaxSize(), true)
|
||||||
objects := NewQuotaStat(*binfo.Objects, (&q).GetMaxObjects(), false)
|
objects := NewQuotaStat(*binfo.Objects, (&q).GetMaxObjects(), false)
|
||||||
return &WebsiteView{wid, size, objects}
|
return &WebsiteView{
|
||||||
|
wid,
|
||||||
|
"not yet implemented",
|
||||||
|
"not yet implemented",
|
||||||
|
size,
|
||||||
|
objects,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type WebsitePatch struct {
|
type WebsitePatch struct {
|
||||||
|
|
175
webui_website.go
Normal file
175
webui_website.go
Normal file
|
@ -0,0 +1,175 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/gorilla/mux"
|
||||||
|
"net/http"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
// --- Start page rendering functions
|
||||||
|
func handleWebsiteList(w http.ResponseWriter, r *http.Request) {
|
||||||
|
user := RequireUserHtml(w, r)
|
||||||
|
if user == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
ctrl, err := NewWebsiteController(user)
|
||||||
|
if err != nil {
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(ctrl.PrettyList) > 0 {
|
||||||
|
http.Redirect(w, r, "/website/inspect/"+ctrl.PrettyList[0], http.StatusFound)
|
||||||
|
} else {
|
||||||
|
http.Redirect(w, r, "/website/new", http.StatusFound)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type WebsiteNewTpl struct {
|
||||||
|
Ctrl *WebsiteController
|
||||||
|
Err error
|
||||||
|
}
|
||||||
|
|
||||||
|
func handleWebsiteNew(w http.ResponseWriter, r *http.Request) {
|
||||||
|
user := RequireUserHtml(w, r)
|
||||||
|
if user == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
ctrl, err := NewWebsiteController(user)
|
||||||
|
if err != nil {
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
tpl := &WebsiteNewTpl{ctrl, nil}
|
||||||
|
|
||||||
|
tWebsiteNew := getTemplate("garage_website_new.html")
|
||||||
|
if r.Method == "POST" {
|
||||||
|
r.ParseForm()
|
||||||
|
|
||||||
|
bucket := strings.Join(r.Form["bucket"], "")
|
||||||
|
if bucket == "" {
|
||||||
|
bucket = strings.Join(r.Form["bucket2"], "")
|
||||||
|
}
|
||||||
|
|
||||||
|
view, err := ctrl.Create(bucket)
|
||||||
|
if err != nil {
|
||||||
|
tpl.Err = err
|
||||||
|
tWebsiteNew.Execute(w, tpl)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
http.Redirect(w, r, "/website/inspect/"+view.Name.Pretty, http.StatusFound)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
tWebsiteNew.Execute(w, tpl)
|
||||||
|
}
|
||||||
|
|
||||||
|
type WebsiteInspectTpl struct {
|
||||||
|
Describe *WebsiteDescribe
|
||||||
|
View *WebsiteView
|
||||||
|
Err error
|
||||||
|
}
|
||||||
|
|
||||||
|
func handleWebsiteInspect(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()
|
||||||
|
action := strings.Join(r.Form["action"], "")
|
||||||
|
switch action {
|
||||||
|
case "increase_quota":
|
||||||
|
_, processErr = ctrl.Patch(bucketName, &WebsitePatch{Size: &user.Quota.WebsiteSizeBursted})
|
||||||
|
case "delete_bucket":
|
||||||
|
processErr = ctrl.Delete(bucketName)
|
||||||
|
if processErr == nil {
|
||||||
|
http.Redirect(w, r, "/website", http.StatusFound)
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
processErr = fmt.Errorf("Unknown action")
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
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}
|
||||||
|
|
||||||
|
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)
|
||||||
|
}
|
Loading…
Reference in a new issue