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) }