package main
import (
"context"
"fmt"
garage "git.deuxfleurs.fr/garage-sdk/garage-admin-sdk-golang"
"github.com/gorilla/mux"
"log"
"net/http"
"strings"
)
func gadmin() (*garage.APIClient, context.Context) {
// Set Host and other parameters
configuration := garage.NewConfiguration()
configuration.Host = config.S3AdminEndpoint
// We can now generate a client
client := garage.NewAPIClient(configuration)
// Authentication is handled through the context pattern
ctx := context.WithValue(context.Background(), garage.ContextAccessToken, config.S3AdminToken)
return client, ctx
}
func grgCreateKey(name string) (*garage.KeyInfo, error) {
client, ctx := gadmin()
kr := garage.AddKeyRequest{Name: &name}
resp, _, err := client.KeyApi.AddKey(ctx).AddKeyRequest(kr).Execute()
if err != nil {
fmt.Printf("%+v\n", err)
return nil, err
}
return resp, nil
}
func grgGetKey(accessKey string) (*garage.KeyInfo, error) {
client, ctx := gadmin()
resp, _, err := client.KeyApi.GetKey(ctx, accessKey).Execute()
if err != nil {
fmt.Printf("%+v\n", err)
return nil, err
}
return resp, nil
}
func grgCreateWebsite(gkey, bucket string, quotas *UserQuota) (*garage.BucketInfo, error) {
client, ctx := gadmin()
br := garage.NewCreateBucketRequest()
br.SetGlobalAlias(bucket)
// Create Bucket
binfo, _, err := client.BucketApi.CreateBucket(ctx).CreateBucketRequest(*br).Execute()
if err != nil {
fmt.Printf("%+v\n", err)
return nil, err
}
// Allow user's key
ar := garage.AllowBucketKeyRequest{
BucketId: *binfo.Id,
AccessKeyId: gkey,
Permissions: *garage.NewAllowBucketKeyRequestPermissions(true, true, true),
}
binfo, _, err = client.BucketApi.AllowBucketKey(ctx).AllowBucketKeyRequest(ar).Execute()
if err != nil {
fmt.Printf("%+v\n", err)
return nil, err
}
// Expose website and set quota
wr := garage.NewUpdateBucketRequestWebsiteAccess()
wr.SetEnabled(true)
wr.SetIndexDocument("index.html")
wr.SetErrorDocument("error.html")
qr := quotas.DefaultWebsiteQuota()
ur := garage.NewUpdateBucketRequest()
ur.SetWebsiteAccess(*wr)
ur.SetQuotas(*qr)
binfo, _, err = client.BucketApi.UpdateBucket(ctx, *binfo.Id).UpdateBucketRequest(*ur).Execute()
if err != nil {
fmt.Printf("%+v\n", err)
return nil, err
}
// Return updated binfo
return binfo, nil
}
func grgAddGlobalAlias(bid, alias string) (*garage.BucketInfo, error) {
client, ctx := gadmin()
resp, _, err := client.BucketApi.PutBucketGlobalAlias(ctx).Id(bid).Alias(alias).Execute()
if err != nil {
log.Println(err)
return nil, err
}
return resp, nil
}
func grgAddLocalAlias(bid, key, alias string) (*garage.BucketInfo, error) {
client, ctx := gadmin()
resp, _, err := client.BucketApi.PutBucketLocalAlias(ctx).Id(bid).AccessKeyId(key).Alias(alias).Execute()
if err != nil {
log.Println(err)
return nil, err
}
return resp, nil
}
func grgDelGlobalAlias(bid, alias string) (*garage.BucketInfo, error) {
client, ctx := gadmin()
resp, _, err := client.BucketApi.DeleteBucketGlobalAlias(ctx).Id(bid).Alias(alias).Execute()
if err != nil {
log.Println(err)
return nil, err
}
return resp, nil
}
func grgDelLocalAlias(bid, key, alias string) (*garage.BucketInfo, error) {
client, ctx := gadmin()
resp, _, err := client.BucketApi.DeleteBucketLocalAlias(ctx).Id(bid).AccessKeyId(key).Alias(alias).Execute()
if err != nil {
log.Println(err)
return nil, err
}
return resp, nil
}
func grgGetBucket(bid string) (*garage.BucketInfo, error) {
client, ctx := gadmin()
resp, _, err := client.BucketApi.GetBucketInfo(ctx, bid).Execute()
if err != nil {
log.Println(err)
return nil, err
}
return resp, nil
}
// --- Start page rendering functions
func handleGarageKey(w http.ResponseWriter, r *http.Request) {
user := RequireUserHtml(w, r)
if user == nil {
return
}
tKey := getTemplate("garage_key.html")
tKey.Execute(w, user)
}
func handleGarageWebsiteList(w http.ResponseWriter, r *http.Request) {
user := RequireUserHtml(w, r)
if user == nil {
return
}
tWebsiteList := getTemplate("garage_website_list.html")
tWebsiteList.Execute(w, user)
}
func handleGarageWebsiteNew(w http.ResponseWriter, r *http.Request) {
user := RequireUserHtml(w, r)
if user == nil {
return
}
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"], "")
}
if bucket == "" {
log.Println("Form empty")
// @FIXME we need to return the error to the user
tWebsiteNew.Execute(w, nil)
return
}
keyInfo, err := user.S3KeyInfo()
if err != nil {
log.Println(err)
// @FIXME we need to return the error to the user
tWebsiteNew.Execute(w, nil)
return
}
binfo, err := grgCreateWebsite(*keyInfo.AccessKeyId, bucket, user.Quota)
if err != nil {
log.Println(err)
// @FIXME we need to return the error to the user
tWebsiteNew.Execute(w, nil)
return
}
http.Redirect(w, r, "/garage/website/b/"+*binfo.Id, http.StatusFound)
return
}
tWebsiteNew.Execute(w, nil)
}
type webInspectView struct {
User *LoggedUser
Bucket *garage.BucketInfo
IndexDoc string
ErrorDoc string
MaxObjects int64
MaxSize int64
UsedSizePct float64
}
func handleGarageWebsiteInspect(w http.ResponseWriter, r *http.Request) {
user := RequireUserHtml(w, r)
if user == nil {
return
}
bucketId := mux.Vars(r)["bucket"]
// @FIXME check that user owns the bucket....
binfo, err := grgGetBucket(bucketId)
if err != nil {
log.Println(err)
return
}
wc := binfo.GetWebsiteConfig()
q := binfo.GetQuotas()
view := webInspectView{
User: user,
Bucket: binfo,
IndexDoc: (&wc).GetIndexDocument(),
ErrorDoc: (&wc).GetErrorDocument(),
MaxObjects: (&q).GetMaxObjects(),
MaxSize: (&q).GetMaxSize(),
}
tWebsiteInspect := getTemplate("garage_website_inspect.html")
tWebsiteInspect.Execute(w, &view)
}