From cd1c12de16e66426490ecf458bece32b77273fc1 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 11 Apr 2023 17:00:14 +0800 Subject: [PATCH 1/4] add bucketacl bucketpolicy multiparts-management --- app/models/app_results.go | 42 +++ app/s3cmd.go | 104 ++++++- app/s3lib/bucket.go | 75 +++++- frontend/src/components/BucketList.vue | 254 +++++++++++++++++- frontend/src/components/manage-multiparts.vue | 138 ++++++++++ frontend/src/components/put-bucket-policy.vue | 137 ++++++++++ 6 files changed, 734 insertions(+), 16 deletions(-) create mode 100644 frontend/src/components/manage-multiparts.vue create mode 100644 frontend/src/components/put-bucket-policy.vue diff --git a/app/models/app_results.go b/app/models/app_results.go index 9c4a4dab..629a2fd7 100644 --- a/app/models/app_results.go +++ b/app/models/app_results.go @@ -18,6 +18,21 @@ type Buckets struct { CreateTime string `json:"createtime"` } +type ListMultipartUploadsResult struct { + Bucket string `json:"bucket"` + IsTruncated bool `json:"is_truncated"` + KeyMarker string `json:"key_marker"` + MaxUploads int `json:"max_uploads"` + Uploads []MultipartUpload `json:"uploads"` +} + +type MultipartUpload struct { + Initiated string `json:"initiated"` + Key string `json:"object_key"` + StorageClass string `json:"storage_class"` + UploadId string `json:"upload_id"` +} + type Object struct { Key string `json:"key"` Size int64 `json:"size"` @@ -71,3 +86,30 @@ type GetObjectVersionsResult struct { Versions []ObjectVersioning `json:"versions"` Err string `json:"err"` } + +type GetBucketAclResult struct { + Grants []Grant `json:"Grants"` +} + +type Grant struct { + Permission string `json:"permission"` + Grantee Grantee `json:"Grantee"` +} + +type Grantee struct { + Type string `json:"type"` + URI string `json:"uri"` +} + +type GetBucketPolicyResult struct { + ID string `json:"id"` + Version string `json:"version"` + Statements []Statement `json:"statement"` +} + +type Statement struct { + Effect string `json:"effect"` + Actions []Action `json:"action"` +} + +type Action string \ No newline at end of file diff --git a/app/s3cmd.go b/app/s3cmd.go index 4572f5a1..552275cc 100644 --- a/app/s3cmd.go +++ b/app/s3cmd.go @@ -3,6 +3,7 @@ package app import ( "bytes" "context" + "encoding/json" "errors" "github.com/wailsapp/wails/v2/pkg/runtime" "io" @@ -25,15 +26,18 @@ func (a *App) ListBuckets() ListBucketsResult { res.Err = err.Error() return res } - for _, bucket := range buckets.Buckets{ - b := Buckets{ - Bucket: *bucket.Name, - CreateTime: (*bucket.CreationDate).Local().Format("2006-01-02 15:04:05"), - //CreateTime: (*bucket.CreationDate).String(), + if buckets != nil{ + for _, bucket := range buckets.Buckets{ + b := Buckets{ + Bucket: *bucket.Name, + CreateTime: (*bucket.CreationDate).Local().Format("2006-01-02 15:04:05"), + //CreateTime: (*bucket.CreationDate).String(), + } + res.Buckets = append(res.Buckets, b) + } + runtime.LogDebug(a.ctx, "ListBuckets success.") + return res } - res.Buckets = append(res.Buckets, b) - } - runtime.LogDebug(a.ctx, "ListBuckets success.") return res } @@ -386,3 +390,87 @@ func (a *App) ListObjectVersions(bucketName string, key string) GetObjectVersion } return res } + +func (a *App) GetBucketAcl(bucketName string) GetBucketAclResult{ + out, err := a.S3Client.GetBucketAcl(bucketName) + if err != nil{ + runtime.LogErrorf(a.ctx, "getbucketacl faild: %s", bucketName) + } + res := GetBucketAclResult{} + for _, grant:=range out.Grants{ + grant1 := Grant{ + Permission: *grant.Permission, + Grantee: Grantee{ + Type: *grant.Grantee.Type, + //URI: *grant.Grantee.URI, + }, + } + res.Grants =append(res.Grants, grant1) + } + return res +} + +func(a *App) SetBucketAcl(bucketName, acl string) string{ + err := a.S3Client.SetBucketAcl(bucketName, acl) + if err != nil { + runtime.LogErrorf(a.ctx, "SetBucketACL %s err: %s ", bucketName, err) + return err.Error() + } + return "" +} + +func(a *App) ListMultipartUploads(bucketName string)(out ListMultipartUploadsResult, err error){ + res, err := a.S3Client.ListMultipartUploads(bucketName) + if err != nil{ + return out, err + } + for _, upload := range res.Uploads{ + upload1 := MultipartUpload{ + Initiated: (*upload.Initiated).Local().Format("2006-01-02 15:04:05"), + Key: *upload.Key, + StorageClass: *upload.StorageClass, + UploadId: *upload.UploadId, + } + out.Uploads = append(out.Uploads, upload1) + } + return out, nil +} + +func(a *App) AbortMultipartUpload(bucketName, key, uploadid string)string{ + err := a.S3Client.AbortMultiPartUpload(bucketName, key, uploadid) + if err!= nil{ + return err.Error() + } + return "" +} + +func(a *App) PutBucketPolicy(bucket, id, action string)string{ + policy_e := `{ + "Version": "2012-10-17", + "ID": "`+ id + `", + "Statement": [{ + "Effect": "Allow", + "Principal": {"AWS":"*"}, + "Action": ["s3:`+action+`"], + "Resource": [ + "arn:aws:s3:::` + bucket + `/*" + ] + }] + }` + err := a.S3Client.PutBucketPolicy(bucket, policy_e) + if err != nil { + return err.Error() + } + return "" +} + +func(a *App) GetBucketPolicy(bucket string) (GetBucketPolicyResult, error) { + res := GetBucketPolicyResult{} + out, err := a.S3Client.GetBucketPolicy(bucket) + if err != nil{ + return res, err} + var p GetBucketPolicyResult + err = json.Unmarshal([]byte(*out.Policy), &p) + return p, err +} + diff --git a/app/s3lib/bucket.go b/app/s3lib/bucket.go index 6f69f2a8..d16a7139 100644 --- a/app/s3lib/bucket.go +++ b/app/s3lib/bucket.go @@ -68,12 +68,13 @@ type Bucket struct { } func (s3client *S3Client) ListBuckets() (buckets *s3.ListBucketsOutput, err error) { +//func (s3client *S3Client) ListBuckets() (bucketnames []string, err error) { params := &s3.ListBucketsInput{} - out, err := s3client.Client.ListBuckets(params) + buckets, err = s3client.Client.ListBuckets(params) if err != nil { return nil, err } - return out, nil + return buckets, nil } func (s3client *S3Client) ListObjects(bucketName, marker, prefix string, maxKeys int64, delemiter string) (*s3.ListObjectsOutput, error) { @@ -86,3 +87,73 @@ func (s3client *S3Client) ListObjects(bucketName, marker, prefix string, maxKeys } return s3client.Client.ListObjects(params) } + +func (s3client *S3Client) GetBucketAcl(bucketname string)(*s3.GetBucketAclOutput, error){ + params := &s3.GetBucketAclInput{ + Bucket: aws.String(bucketname), + } + out, err := s3client.Client.GetBucketAcl(params) + return out, err +} + +func (s3client *S3Client) SetBucketAcl(bucketname, acl string) (err error){ + params := &s3.PutBucketAclInput{ + Bucket: aws.String(bucketname), + ACL: aws.String(acl), + } + _, err = s3client.Client.PutBucketAcl(params) + return err +} + +func (s3client *S3Client) SetBucketAclPolicy(bucketname string, acl *s3.AccessControlPolicy)(err error){ + params := &s3.PutBucketAclInput{ + Bucket: aws.String(bucketname), + AccessControlPolicy: acl, + } + _, err = s3client.Client.PutBucketAcl(params) + return err +} + +func (s3client *S3Client) ListMultipartUploads(bucketname string) (ListMultiparts *s3.ListMultipartUploadsOutput, err error) { + params := &s3.ListMultipartUploadsInput{ + Bucket: aws.String(bucketname), + } + + out, err :=s3client.Client.ListMultipartUploads(params) + if err != nil{ + return nil, err + } + return out, nil +} + +func (s3client *S3Client) AbortMultipartUpload(bucketname, key, uploadid string) string{ + params := &s3.AbortMultipartUploadInput{ + Bucket: aws.String(bucketname), + Key: aws.String(key), + UploadId: aws.String(uploadid), + } + _, err := s3client.Client.AbortMultipartUpload(params) + if err != nil{ + return err.Error() + } + return "" +} + +func (s3client *S3Client) PutBucketPolicy(bucketname, policy string) error{ + params := &s3.PutBucketPolicyInput{ + Bucket: aws.String(bucketname), + Policy: aws.String(policy), + } + _, err := s3client.Client.PutBucketPolicy(params) + if err != nil{ + return err + } + return nil +} + +func (s3client *S3Client) GetBucketPolicy(bucketname string)(*s3.GetBucketPolicyOutput, error){ + params := &s3.GetBucketPolicyInput{ + Bucket: aws.String(bucketname)} + out, err := s3client.Client.GetBucketPolicy(params) + return out, err +} \ No newline at end of file diff --git a/frontend/src/components/BucketList.vue b/frontend/src/components/BucketList.vue index 4dc7c81a..648a62de 100644 --- a/frontend/src/components/BucketList.vue +++ b/frontend/src/components/BucketList.vue @@ -5,9 +5,27 @@ Create Bucket + + 碎片 + + + 设置acl权限 + + + 简化policy授权 + + + + + - + + + + @@ -23,15 +41,43 @@ + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ diff --git a/frontend/src/components/put-bucket-policy.vue b/frontend/src/components/put-bucket-policy.vue new file mode 100644 index 00000000..c911be82 --- /dev/null +++ b/frontend/src/components/put-bucket-policy.vue @@ -0,0 +1,137 @@ + + + From 6bb47f19adeeaafadc0fc17b84fd9d8b8bff1f08 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 11 Apr 2023 17:26:49 +0800 Subject: [PATCH 2/4] fix createbucket bucketname cant clear after cancel --- frontend/src/components/BucketList.vue | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/frontend/src/components/BucketList.vue b/frontend/src/components/BucketList.vue index 648a62de..09e845c5 100644 --- a/frontend/src/components/BucketList.vue +++ b/frontend/src/components/BucketList.vue @@ -323,7 +323,8 @@ export default { data.tableData = [] listBuckets() } - } + }, + form.bucketname='' ) } From d68882ac7dafc7751dae19afdb85ca30c6ccfe30 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 12 Apr 2023 10:03:19 +0800 Subject: [PATCH 3/4] remove useless explanatory note --- frontend/src/components/BucketList.vue | 79 +++++--------------------- 1 file changed, 14 insertions(+), 65 deletions(-) diff --git a/frontend/src/components/BucketList.vue b/frontend/src/components/BucketList.vue index 09e845c5..9c4a7792 100644 --- a/frontend/src/components/BucketList.vue +++ b/frontend/src/components/BucketList.vue @@ -50,7 +50,7 @@ align-center destroy-on-close > - + @@ -76,8 +76,7 @@ v-loading="loading" @current-change="handleCurrentChange" > - - + - - - - - - - - - - - - - - - - - - - - - - - @@ -158,7 +134,6 @@ import { MakeBucket, GetBucketAcl, SetBucketAcl, - ListMultipartUploads, } from "../../wailsjs/go/app/App"; import {ElMessage, ElMessageBox, ElTable} from "element-plus"; import {useRouter} from "vue-router" @@ -171,7 +146,7 @@ export default { setup() { const loading = ref(true) let bucket = ref('') - let radio1 = ref('') + let bucketaclsetting = ref('') let form = reactive({ bucketname: '', }) @@ -188,9 +163,8 @@ export default { const currentRow = ref() const testDom = ref(null) const testMul = ref(null) - // let flag=ref(false) + const openByParentMethod = () => { - // flag.value=true testDom.value.dialogVisble = true testMul.value.dialoglistmultiparts = true } @@ -198,7 +172,7 @@ export default { testDom.value.dialogVisble = false testMul.value.dialoglistmultiparts = false } - // const singleTableRef = ref>() + const handleCurrentChange = (val= bucketList | undefined) => { currentRow.value = val // console.log(currentRow.value.name) @@ -215,10 +189,6 @@ export default { listBuckets() }) - const audit=(row)=>{ - bucketname = row.name - } - const state = reactive({ flag: false, showmultipart: false @@ -243,11 +213,6 @@ export default { ListBuckets(); } - // const handledisablebucketacl=()=>{ - // disablesetbucketacl.value = currentRow.value === undefined - // console.log(disablesetbucketacl.value) - // } - const listBuckets = () => { ListBuckets().then(res => { loading.value = true @@ -301,17 +266,6 @@ export default { }) } - const handleMoreOperation = (command) =>{ - if (command === "deletebucket"){ - confirmDeleteBucket() - }else if (command==="setbucketacl"){ - centerDialogVisible = true - // setbucketaclDialogVisible.value = false - // toSetBucketAcl() - // setBucketAcl() - } - } - const toCreateBucket = () => { dialogFormVisible.value = false MakeBucket(form.bucketname).then(res => { @@ -329,32 +283,31 @@ export default { } const toGetBucketAcl = () => { - // console.log(currentRow.value) GetBucketAcl(currentRow.value.name).then(res => { if (res.Grants !== '' && res.Grants.length===1){ - radio1.value = "私有" + bucketaclsetting.value = "私有" } if (res.Grants !== '' && res.Grants.length===2){ - radio1.value = "公共读" + bucketaclsetting.value = "公共读" } if (res.Grants !== '' && res.Grants.length===3){ - radio1.value = "公共读写" + bucketaclsetting.value = "公共读写" } - console.log(radio1) + console.log(bucketaclsetting) }) } const toSetBucketAcl = () => { centerDialogVisible.value=false let acl = '' - // console.log(radio1) - if (radio1.value === "私有"){ + // console.log(bucketaclsetting) + if (bucketaclsetting.value === "私有"){ acl = "private" } - if (radio1.value === "公共读"){ + if (bucketaclsetting.value === "公共读"){ acl = "public-read" } - if (radio1.value === "公共读写") { + if (bucketaclsetting.value === "公共读写") { acl = "public-read-write" } SetBucketAcl(currentRow.value.name, acl).then(res =>{ @@ -363,8 +316,6 @@ export default { }else { ElMessage.success("set bucket acl success") listBuckets() - // form.bucketname = '' - // form.acl = '' } } ) @@ -385,7 +336,7 @@ export default { ...toRefs(data), form, loading, - radio1, + bucketaclsetting, bucket, open, openlistmul, @@ -399,8 +350,6 @@ export default { toGetBucketAcl, toDeleteBucket, toSetBucketAcl, - audit, - handleMoreOperation, handleCurrentChange, toBucket, listBuckets, From d53241ca7e68cb2d1b7565e0bdfc6898c28851c9 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 12 Apr 2023 10:08:14 +0800 Subject: [PATCH 4/4] remove debug log --- app/s3cmd.go | 3 --- 1 file changed, 3 deletions(-) diff --git a/app/s3cmd.go b/app/s3cmd.go index 552275cc..967e1bea 100644 --- a/app/s3cmd.go +++ b/app/s3cmd.go @@ -22,7 +22,6 @@ func (a *App) ListBuckets() ListBucketsResult { res := ListBucketsResult{} buckets, err := a.S3Client.ListBuckets() if err != nil { - runtime.LogErrorf(a.ctx, "ListBuckets err: %s ", err) res.Err = err.Error() return res } @@ -31,11 +30,9 @@ func (a *App) ListBuckets() ListBucketsResult { b := Buckets{ Bucket: *bucket.Name, CreateTime: (*bucket.CreationDate).Local().Format("2006-01-02 15:04:05"), - //CreateTime: (*bucket.CreationDate).String(), } res.Buckets = append(res.Buckets, b) } - runtime.LogDebug(a.ctx, "ListBuckets success.") return res } return res