diff options
-rw-r--r-- | garage.go | 368 | ||||
-rw-r--r-- | main.go | 26 |
2 files changed, 197 insertions, 197 deletions
@@ -1,116 +1,114 @@ package main import ( - "errors" - "log" - "net/http" - "context" - "fmt" - "strings" + "context" + "errors" + "fmt" + garage "git.deuxfleurs.fr/garage-sdk/garage-admin-sdk-golang" "github.com/go-ldap/ldap/v3" "github.com/gorilla/mux" - garage "git.deuxfleurs.fr/garage-sdk/garage-admin-sdk-golang" + "log" + "net/http" + "strings" ) func gadmin() (*garage.APIClient, context.Context) { - // Set Host and other parameters - configuration := garage.NewConfiguration() - configuration.Host = config.S3AdminEndpoint + // Set Host and other parameters + configuration := garage.NewConfiguration() + configuration.Host = config.S3AdminEndpoint - // We can now generate a client - client := garage.NewAPIClient(configuration) + // 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 + // 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 + 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 + 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) (*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 := garage.NewUpdateBucketRequestQuotas() - qr.SetMaxSize(1024 * 1024 * 50) // 50MB - qr.SetMaxObjects(10000) //10k objects - - 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 + 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 := garage.NewUpdateBucketRequestQuotas() + qr.SetMaxSize(1024 * 1024 * 50) // 50MB + qr.SetMaxObjects(10000) //10k objects + + 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 grgGetBucket(bid string) (*garage.BucketInfo, error) { - client, ctx := gadmin() + client, ctx := gadmin() - resp, _, err := client.BucketApi.GetBucketInfo(ctx, bid).Execute() - if err != nil { - fmt.Printf("%+v\n", err) - return nil, err - } - return resp, nil + resp, _, err := client.BucketApi.GetBucketInfo(ctx, bid).Execute() + if err != nil { + fmt.Printf("%+v\n", err) + return nil, err + } + return resp, nil } - func checkLoginAndS3(w http.ResponseWriter, r *http.Request) (*LoginStatus, *garage.KeyInfo, error) { login := checkLogin(w, r) if login == nil { @@ -118,134 +116,136 @@ func checkLoginAndS3(w http.ResponseWriter, r *http.Request) (*LoginStatus, *gar } keyID := login.UserEntry.GetAttributeValue("garage_s3_access_key") - if keyID == "" { - keyPair, err := grgCreateKey(login.Info.Username) - if err != nil { - return login, nil, err - } + if keyID == "" { + keyPair, err := grgCreateKey(login.Info.Username) + if err != nil { + return login, nil, err + } modify_request := ldap.NewModifyRequest(login.Info.DN, nil) modify_request.Replace("garage_s3_access_key", []string{*keyPair.AccessKeyId}) - // @FIXME compatibility feature for bagage (SFTP+webdav) - // you can remove it once bagage will be updated to fetch the key from garage directly - // or when bottin will be able to dynamically fetch it. + // @FIXME compatibility feature for bagage (SFTP+webdav) + // you can remove it once bagage will be updated to fetch the key from garage directly + // or when bottin will be able to dynamically fetch it. modify_request.Replace("garage_s3_secret_key", []string{*keyPair.SecretAccessKey}) - err = login.conn.Modify(modify_request) - return login, keyPair, err - } - // Note: we could simply return the login info, but LX asked we do not - // store the secrets in LDAP in the future. - keyPair, err := grgGetKey(keyID) - return login, keyPair, err + err = login.conn.Modify(modify_request) + return login, keyPair, err + } + // Note: we could simply return the login info, but LX asked we do not + // store the secrets in LDAP in the future. + keyPair, err := grgGetKey(keyID) + return login, keyPair, err } type keyView struct { - Status *LoginStatus - Key *garage.KeyInfo + Status *LoginStatus + Key *garage.KeyInfo } func handleGarageKey(w http.ResponseWriter, r *http.Request) { - login, s3key, err := checkLoginAndS3(w, r) - if err != nil { - log.Println(err) - return - } - view := keyView{Status: login, Key: s3key} - - tKey := getTemplate("garage_key.html") + login, s3key, err := checkLoginAndS3(w, r) + if err != nil { + log.Println(err) + return + } + view := keyView{Status: login, Key: s3key} + + tKey := getTemplate("garage_key.html") tKey.Execute(w, &view) } type webListView struct { - Status *LoginStatus - Key *garage.KeyInfo + Status *LoginStatus + Key *garage.KeyInfo } + func handleGarageWebsiteList(w http.ResponseWriter, r *http.Request) { - login, s3key, err := checkLoginAndS3(w, r) - if err != nil { - log.Println(err) - return - } - view := webListView{Status: login, Key: s3key} - - tWebsiteList := getTemplate("garage_website_list.html") + login, s3key, err := checkLoginAndS3(w, r) + if err != nil { + log.Println(err) + return + } + view := webListView{Status: login, Key: s3key} + + tWebsiteList := getTemplate("garage_website_list.html") tWebsiteList.Execute(w, &view) } func handleGarageWebsiteNew(w http.ResponseWriter, r *http.Request) { - _, s3key, err := checkLoginAndS3(w, r) - if err != nil { - log.Println(err) - return - } + _, s3key, err := checkLoginAndS3(w, r) + if err != nil { + log.Println(err) + return + } - tWebsiteNew := getTemplate("garage_website_new.html") + tWebsiteNew := getTemplate("garage_website_new.html") if r.Method == "POST" { - r.ParseForm() - log.Println(r.Form) + r.ParseForm() + log.Println(r.Form) 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 - } - - binfo, err := grgCreateWebsite(*s3key.AccessKeyId, bucket) - 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 - } + 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 + } + + binfo, err := grgCreateWebsite(*s3key.AccessKeyId, bucket) + 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 { - Status *LoginStatus - Key *garage.KeyInfo - Bucket *garage.BucketInfo - IndexDoc string - ErrorDoc string - MaxObjects int64 - MaxSize int64 - UsedSizePct float64 + Status *LoginStatus + Key *garage.KeyInfo + Bucket *garage.BucketInfo + IndexDoc string + ErrorDoc string + MaxObjects int64 + MaxSize int64 + UsedSizePct float64 } + func handleGarageWebsiteInspect(w http.ResponseWriter, r *http.Request) { - login, s3key, err := checkLoginAndS3(w, r) - if err != nil { - log.Println(err) - return - } + login, s3key, err := checkLoginAndS3(w, r) + if err != nil { + log.Println(err) + return + } bucketId := mux.Vars(r)["bucket"] - binfo, err := grgGetBucket(bucketId) - if err != nil { - log.Println(err) - return - } - - wc := binfo.GetWebsiteConfig() - q := binfo.GetQuotas() - - view := webInspectView { - Status: login, - Key: s3key, - Bucket: binfo, - IndexDoc: (&wc).GetIndexDocument(), - ErrorDoc: (&wc).GetErrorDocument(), - MaxObjects: (&q).GetMaxObjects(), - MaxSize: (&q).GetMaxSize(), - } - - tWebsiteInspect := getTemplate("garage_website_inspect.html") + binfo, err := grgGetBucket(bucketId) + if err != nil { + log.Println(err) + return + } + + wc := binfo.GetWebsiteConfig() + q := binfo.GetQuotas() + + view := webInspectView{ + Status: login, + Key: s3key, + Bucket: binfo, + IndexDoc: (&wc).GetIndexDocument(), + ErrorDoc: (&wc).GetErrorDocument(), + MaxObjects: (&q).GetMaxObjects(), + MaxSize: (&q).GetMaxSize(), + } + + tWebsiteInspect := getTemplate("garage_website_inspect.html") tWebsiteInspect.Execute(w, &view) } @@ -48,8 +48,8 @@ type ConfigFile struct { GroupCanInvite string `json:"group_can_invite"` GroupCanAdmin string `json:"group_can_admin"` - S3AdminEndpoint string `json:"s3_admin_endpoint"` - S3AdminToken string `json:"s3_admin_token"` + S3AdminEndpoint string `json:"s3_admin_endpoint"` + S3AdminToken string `json:"s3_admin_token"` S3Endpoint string `json:"s3_endpoint"` S3AccessKey string `json:"s3_access_key"` @@ -105,12 +105,12 @@ func readConfig() ConfigFile { } func getTemplate(name string) *template.Template { - return template.Must(template.New("layout.html").Funcs(template.FuncMap { - "contains": strings.Contains, - }).ParseFiles( - templatePath+"/layout.html", - templatePath+"/"+name, - )) + return template.Must(template.New("layout.html").Funcs(template.FuncMap{ + "contains": strings.Contains, + }).ParseFiles( + templatePath+"/layout.html", + templatePath+"/"+name, + )) } func main() { @@ -137,10 +137,10 @@ func main() { r.HandleFunc("/directory/search", handleDirectorySearch) r.HandleFunc("/directory", handleDirectory) - r.HandleFunc("/garage/key", handleGarageKey) - r.HandleFunc("/garage/website", handleGarageWebsiteList) - r.HandleFunc("/garage/website/new", handleGarageWebsiteNew) - r.HandleFunc("/garage/website/b/{bucket}", handleGarageWebsiteInspect) + r.HandleFunc("/garage/key", handleGarageKey) + r.HandleFunc("/garage/website", handleGarageWebsiteList) + r.HandleFunc("/garage/website/new", handleGarageWebsiteNew) + r.HandleFunc("/garage/website/b/{bucket}", handleGarageWebsiteInspect) r.HandleFunc("/invite/new_account", handleInviteNewAccount) r.HandleFunc("/invite/send_code", handleInviteSendCode) @@ -260,7 +260,7 @@ func checkLogin(w http.ResponseWriter, r *http.Request) *LoginStatus { "mail", "memberof", "description", - "garage_s3_access_key", + "garage_s3_access_key", FIELD_NAME_DIRECTORY_VISIBILITY, FIELD_NAME_PROFILE_PICTURE, }, |