aboutsummaryrefslogtreecommitdiff
path: root/api.go
diff options
context:
space:
mode:
Diffstat (limited to 'api.go')
-rw-r--r--api.go149
1 files changed, 136 insertions, 13 deletions
diff --git a/api.go b/api.go
index bce9993..1ddb4ea 100644
--- a/api.go
+++ b/api.go
@@ -2,11 +2,12 @@ package main
import (
//"context"
+ "encoding/json"
"errors"
"fmt"
garage "git.deuxfleurs.fr/garage-sdk/garage-admin-sdk-golang"
"github.com/go-ldap/ldap/v3"
- //"github.com/gorilla/mux"
+ "github.com/gorilla/mux"
"log"
"net/http"
"strings"
@@ -111,21 +112,132 @@ func checkLoginAndS3API(w http.ResponseWriter, r *http.Request) (*LoginStatus, *
return login, keyPair, err
}
+type ApiQuotaView struct {
+ files *uint64
+ size *uint64
+}
+
+type ApiBucketView struct {
+ global *bool
+ max *ApiQuotaView
+ used *ApiQuotaView
+}
+
+type BucketRequest struct {
+ s3key *garage.KeyInfo
+ bucketName string
+ bucketId string
+ global bool
+ http *http.Request
+}
+
func handleAPIGarageBucket(w http.ResponseWriter, r *http.Request) {
- login, s3key, err := checkLoginAndS3API(w, r)
+ br, err := buildBucketRequest(w, r)
+ if err != nil {
+ return
+ }
+
+ if r.Method == http.MethodPatch {
+ patchGarageBucket(w, br)
+ return
+ }
+
+ if r.Method == http.MethodGet {
+ getGarageBucket(w, br)
+ return
+ }
+
+ http.Error(w, "This method is not implemented for this endpoint", http.StatusNotImplemented)
+ return
+}
+
+func buildBucketRequest(w http.ResponseWriter, r *http.Request) (*BucketRequest, error) {
+ _, s3key, err := checkLoginAndS3API(w, r)
+ if err != nil {
+ http.Error(w, "Unable to connect on LDAP", http.StatusUnauthorized)
+ return nil, err
+ }
+
+ // FETCH BUCKET ID by iterating over buckets owned by this key
+ bucketName := mux.Vars(r)["bucket"]
+ var bucketId *string
+ var global *bool
+
+findBucketIdLoop:
+ for _, bucket := range s3key.Buckets {
+ for _, localAlias := range bucket.LocalAliases {
+ if localAlias == bucketName {
+ bucketId = bucket.Id
+ *global = false
+ break findBucketIdLoop
+ }
+ }
+ for _, globalAlias := range bucket.GlobalAliases {
+ if globalAlias == bucketName {
+ bucketId = bucket.Id
+ *global = true
+ break findBucketIdLoop
+ }
+ }
+ }
+
+ if bucketId == nil || global == nil {
+ http.Error(w, "Bucket not found in this account", http.StatusNotFound)
+ return nil, errors.New("Unable to fetch bucket ID")
+ }
+
+ return &BucketRequest{
+ s3key: s3key,
+ bucketName: bucketName,
+ bucketId: *bucketId,
+ global: *global,
+ http: r,
+ }, nil
+}
+
+func patchGarageBucket(w http.ResponseWriter, br *BucketRequest) {
+ var err error
+
+ // DECODE BODY
+ var queuedChange ApiBucketView
+ decoder := json.NewDecoder(br.http.Body)
+ err = decoder.Decode(&queuedChange)
if err != nil {
log.Println(err)
+ http.Error(w, "Unable to decode the body", http.StatusBadRequest)
return
}
- // CHECK PATCH REQUEST
+ // SET THE GLOBAL FLAG
+ if queuedChange.global != nil {
+ if *queuedChange.global && !br.global {
+ _, err = grgAddGlobalAlias(br.bucketId, br.bucketName)
+ if err != nil {
+ http.Error(w, "Unable to add the requested name as global alias for this bucket", http.StatusInternalServerError)
+ return
+ }
+ _, err = grgDelLocalAlias(br.bucketId, *br.s3key.AccessKeyId, br.bucketName)
+ if err != nil {
+ http.Error(w, "Unable to remove the local alias for this bucket", http.StatusInternalServerError)
+ return
+ }
+ } else if !*queuedChange.global && br.global {
+ grgAddLocalAlias(br.bucketId, *br.s3key.AccessKeyId, br.bucketName)
+ if err != nil {
+ http.Error(w, "Unable to add the requested name as local alias for this bucket", http.StatusInternalServerError)
+ return
+ }
+ grgDelGlobalAlias(br.bucketId, br.bucketName)
+ if err != nil {
+ http.Error(w, "Unable to remove the global alias for this bucket", http.StatusInternalServerError)
+ return
+ }
+ }
+ }
- // READ BODY JSON
+ // CHECK IF QUOTA MUST BE ADDED TO THIS BUCKET
- // VALIDATE OBJECT
- // --- bucket query parameter ---
- // 1. bucket must be owned by the key with owner permission, otherwise throw "unauthorized" (401)
- // 2. must not end with deuxfleurs.fr or deuxfleurs.org, otherwise throw "forbidden" (403)
+ // VALIDATE IT
// --- global ---
// 1. can be true, false, or nil (use pointers)
// 2. if nil do nothing
@@ -137,17 +249,28 @@ func handleAPIGarageBucket(w http.ResponseWriter, r *http.Request) {
// --- quota.files ---
// 1. if no quota on the bucket + this field is none, set to 10k
// 2. if lower than 10k, set to 10k. If higher than 40k, set to 40k
+ // READ BODY JSON
// IF BODY.GLOBAL is not NONE
- // Add an alias
+ // DO: Add an alias
// IF BODY.QUOTA.SIZE is not NONE
- // Change quota
+ // DO: Change quota
// IF BODY.QUOTA.FILE is not NONE
- // Change quota
+ // DO: Change quota
- log.Println(login, s3key)
+ getGarageBucket(w, br)
+}
- return
+func getGarageBucket(w http.ResponseWriter, br *BucketRequest) {
+ // FETCH AN UPDATED BUCKET VIEW
+ bucket, err := grgGetBucket(br.bucketId)
+ if err != nil {
+ http.Error(w, "Unable to fetch bucket details", http.StatusInternalServerError)
+ return
+ }
+
+ // BUILD A VIEW
+ log.Println(bucket)
}