(0);
const internalPaths = get(match.params, "subpaths", "");
+ const internalPathsDecoded = atob(internalPaths) || "";
const bucketName = match.params["bucketName"];
- const allPathData = internalPaths.split("/");
- const currentItem = allPathData.pop();
+ const allPathData = internalPathsDecoded.split("/");
+ const currentItem = allPathData.pop() || "";
+
+ // calculate object name to display
+ let objectNameArray: string[] = [];
+ if (actualInfo) {
+ objectNameArray = actualInfo.name.split("/");
+ }
useEffect(() => {
if (loadObjectData) {
- const encodedPath = encodeURIComponent(internalPaths);
api
.invoke(
"GET",
- `/api/v1/buckets/${bucketName}/objects?prefix=${encodedPath}${
+ `/api/v1/buckets/${bucketName}/objects?prefix=${internalPaths}${
distributedSetup ? "&with_versions=true" : ""
}`
)
@@ -299,11 +306,10 @@ const ObjectDetails = ({
useEffect(() => {
if (metadataLoad) {
- const encodedPath = encodeURIComponent(internalPaths);
api
.invoke(
"GET",
- `/api/v1/buckets/${bucketName}/objects?prefix=${encodedPath}&with_metadata=true`
+ `/api/v1/buckets/${bucketName}/objects?prefix=${internalPaths}&with_metadata=true`
)
.then((res: FileInfoResponse) => {
const fileData = res.objects[0];
@@ -340,6 +346,7 @@ const ObjectDetails = ({
};
const closeShareModal = () => {
+ setObjectToShare(null);
setShareFileModalOpen(false);
};
@@ -367,8 +374,11 @@ const ObjectDetails = ({
const tableActions: ItemActions[] = [
{
type: "share",
- onClick: shareObject,
- sendOnlyId: true,
+ onClick: (item: any) => {
+ setObjectToShare(item);
+ shareObject();
+ },
+ sendOnlyId: false,
disableButtonFunction: (item: string) => {
const element = versions.find((elm) => elm.version_id === item);
if (element && element.is_delete_marker) {
@@ -445,7 +455,7 @@ const ObjectDetails = ({
open={shareFileModalOpen}
closeModalAndRefresh={closeShareModal}
bucketName={bucketName}
- dataObject={actualInfo}
+ dataObject={objectToShare || actualInfo}
/>
)}
{retentionModalOpen && actualInfo && (
@@ -479,7 +489,7 @@ const ObjectDetails = ({
@@ -512,12 +522,16 @@ const ObjectDetails = ({
}
- title={currentItem}
+ title={
+ objectNameArray.length > 0
+ ? objectNameArray[objectNameArray.length - 1]
+ : actualInfo.name
+ }
subTitle={
}
@@ -655,7 +669,7 @@ const ObjectDetails = ({
|
{actualInfo.retention_mode
? actualInfo.retention_mode.toLowerCase()
- : "Undefined"}
+ : "None"}
{
diff --git a/portal-ui/src/screens/Console/Buckets/ListBuckets/Objects/ObjectDetails/SetRetention.tsx b/portal-ui/src/screens/Console/Buckets/ListBuckets/Objects/ObjectDetails/SetRetention.tsx
index dc552524c..f38db842a 100644
--- a/portal-ui/src/screens/Console/Buckets/ListBuckets/Objects/ObjectDetails/SetRetention.tsx
+++ b/portal-ui/src/screens/Console/Buckets/ListBuckets/Objects/ObjectDetails/SetRetention.tsx
@@ -119,7 +119,9 @@ const SetRetention = ({
api
.invoke(
"PUT",
- `/api/v1/buckets/${bucketName}/objects/retention?prefix=${selectedObject}&version_id=${versionId}`,
+ `/api/v1/buckets/${bucketName}/objects/retention?prefix=${btoa(
+ selectedObject
+ )}&version_id=${versionId}`,
{
expires: expireDate,
mode: type,
@@ -142,7 +144,9 @@ const SetRetention = ({
api
.invoke(
"DELETE",
- `/api/v1/buckets/${bucketName}/objects/retention?prefix=${selectedObject}&version_id=${versionId}`
+ `/api/v1/buckets/${bucketName}/objects/retention?prefix=${btoa(
+ selectedObject
+ )}&version_id=${versionId}`
)
.then(() => {
setIsSaving(false);
diff --git a/portal-ui/src/screens/Console/Buckets/ListBuckets/Objects/ObjectDetails/ShareFile.tsx b/portal-ui/src/screens/Console/Buckets/ListBuckets/Objects/ObjectDetails/ShareFile.tsx
index ad1c85c05..dabd3f25a 100644
--- a/portal-ui/src/screens/Console/Buckets/ListBuckets/Objects/ObjectDetails/ShareFile.tsx
+++ b/portal-ui/src/screens/Console/Buckets/ListBuckets/Objects/ObjectDetails/ShareFile.tsx
@@ -100,9 +100,9 @@ const ShareFile = ({
api
.invoke(
"GET",
- `/api/v1/buckets/${bucketName}/objects/share?prefix=${
+ `/api/v1/buckets/${bucketName}/objects/share?prefix=${btoa(
dataObject.name
- }&version_id=${versID || "null"}${
+ )}&version_id=${versID || "null"}${
selectedDate !== "" ? `&expires=${diffDate}ms` : ""
}`
)
diff --git a/portal-ui/src/screens/Console/Buckets/ListBuckets/Objects/Preview/PreviewFileContent.tsx b/portal-ui/src/screens/Console/Buckets/ListBuckets/Objects/Preview/PreviewFileContent.tsx
index fa167f3bb..e39463b03 100644
--- a/portal-ui/src/screens/Console/Buckets/ListBuckets/Objects/Preview/PreviewFileContent.tsx
+++ b/portal-ui/src/screens/Console/Buckets/ListBuckets/Objects/Preview/PreviewFileContent.tsx
@@ -72,7 +72,7 @@ const PreviewFile = ({
let path = "";
if (object) {
- const encodedPath = encodeURIComponent(object.name);
+ const encodedPath = btoa(object.name);
path = `${window.location.origin}/api/v1/buckets/${bucketName}/objects/download?preview=true&prefix=${encodedPath}`;
if (object.version_id) {
path = path.concat(`&version_id=${object.version_id}`);
diff --git a/portal-ui/src/screens/Console/Buckets/ListBuckets/Objects/utils.ts b/portal-ui/src/screens/Console/Buckets/ListBuckets/Objects/utils.ts
index 9ddd48291..1797700a5 100644
--- a/portal-ui/src/screens/Console/Buckets/ListBuckets/Objects/utils.ts
+++ b/portal-ui/src/screens/Console/Buckets/ListBuckets/Objects/utils.ts
@@ -14,8 +14,6 @@
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see .
-import { isNullOrUndefined } from "util";
-
export const download = (
bucketName: string,
objectPath: string,
@@ -25,9 +23,9 @@ export const download = (
) => {
const anchor = document.createElement("a");
document.body.appendChild(anchor);
- const encodedPath = encodeURIComponent(objectPath);
+ const encodedPath = btoa(objectPath);
let path = `/api/v1/buckets/${bucketName}/objects/download?prefix=${encodedPath}`;
- if (!isNullOrUndefined(versionID) && versionID !== "null") {
+ if (versionID) {
path = path.concat(`&version_id=${versionID}`);
}
window.location.href = path;
diff --git a/portal-ui/src/screens/Console/ObjectBrowser/BrowserBreadcrumbs.tsx b/portal-ui/src/screens/Console/ObjectBrowser/BrowserBreadcrumbs.tsx
index 1246ceda0..4f1be03b3 100644
--- a/portal-ui/src/screens/Console/ObjectBrowser/BrowserBreadcrumbs.tsx
+++ b/portal-ui/src/screens/Console/ObjectBrowser/BrowserBreadcrumbs.tsx
@@ -55,20 +55,16 @@ const BrowserBreadcrumbs = ({
paths = `/${internalPaths}`;
}
- const splitPaths = paths.split("/");
-
+ const splitPaths = paths.split("/").filter((path) => path !== "");
const listBreadcrumbs = splitPaths.map(
(objectItem: string, index: number) => {
- const subSplit = splitPaths.slice(1, index + 1).join("/");
-
- const route = `/buckets/${bucketName}/browse${
- objectItem !== "" ? `/${subSplit}` : ""
+ const subSplit = splitPaths.slice(0, index + 1).join("/");
+ const route = `/buckets/${bucketName}/browse/${
+ subSplit ? `${btoa(subSplit)}` : ``
}`;
- const label = objectItem === "" ? bucketName : objectItem;
-
return (
- {label}
+ {objectItem}
{index < splitPaths.length - 1 && / }
);
@@ -95,6 +91,10 @@ const BrowserBreadcrumbs = ({
)}
+
+ {bucketName}
+ {listBreadcrumbs.length > 0 && / }
+
{listBreadcrumbs}
diff --git a/restapi/user_buckets.go b/restapi/user_buckets.go
index 76cdd0b28..e1861d956 100644
--- a/restapi/user_buckets.go
+++ b/restapi/user_buckets.go
@@ -18,6 +18,7 @@ package restapi
import (
"context"
+ "encoding/base64"
"encoding/json"
"fmt"
"strings"
@@ -835,13 +836,15 @@ func getBucketObjectLockingResponse(session *models.Principal, bucketName string
func getBucketRewindResponse(session *models.Principal, params user_api.GetBucketRewindParams) (*models.RewindResponse, *models.Error) {
ctx, cancel := context.WithTimeout(context.Background(), time.Second*20)
defer cancel()
-
var prefix = ""
-
if params.Prefix != nil {
- prefix = *params.Prefix
+ encodedPrefix := *params.Prefix
+ decodedPrefix, err := base64.StdEncoding.DecodeString(encodedPrefix)
+ if err != nil {
+ return nil, prepareError(err)
+ }
+ prefix = string(decodedPrefix)
}
-
s3Client, err := newS3BucketClient(session, params.BucketName, prefix)
if err != nil {
LogError("error creating S3Client: %v", err)
diff --git a/restapi/user_objects.go b/restapi/user_objects.go
index e6f292886..f4f734df6 100644
--- a/restapi/user_objects.go
+++ b/restapi/user_objects.go
@@ -18,6 +18,7 @@ package restapi
import (
"context"
+ "encoding/base64"
"fmt"
"io"
"log"
@@ -83,8 +84,21 @@ func registerObjectsHandlers(api *operations.ConsoleAPI) {
defer resp.Close()
// indicate it's a download / inline content to the browser, and the size of the object
- filename := params.Prefix
+ var prefixPath string
+ var filename string
+ if params.Prefix != "" {
+ encodedPrefix := params.Prefix
+ decodedPrefix, err := base64.StdEncoding.DecodeString(encodedPrefix)
+ if err != nil {
+ log.Println(err)
+ }
+ prefixPath = string(decodedPrefix)
+ }
+ prefixElements := strings.Split(prefixPath, "/")
+ if len(prefixElements) > 0 {
+ filename = prefixElements[len(prefixElements)-1]
+ }
if isPreview {
rw.Header().Set("Content-Disposition", fmt.Sprintf("inline; filename=\"%s\"", filename))
rw.Header().Set("X-Frame-Options", "SAMEORIGIN")
@@ -172,9 +186,13 @@ func getListObjectsResponse(session *models.Principal, params user_api.ListObjec
var recursive bool
var withVersions bool
var withMetadata bool
-
if params.Prefix != nil {
- prefix = *params.Prefix
+ encodedPrefix := *params.Prefix
+ decodedPrefix, err := base64.StdEncoding.DecodeString(encodedPrefix)
+ if err != nil {
+ return nil, prepareError(err)
+ }
+ prefix = string(decodedPrefix)
}
if params.Recursive != nil {
recursive = *params.Recursive
@@ -270,7 +288,16 @@ func listBucketObjects(ctx context.Context, client MinioClient, bucketName strin
func getDownloadObjectResponse(session *models.Principal, params user_api.DownloadObjectParams) (io.ReadCloser, *models.Error) {
ctx := context.Background()
- s3Client, err := newS3BucketClient(session, params.BucketName, params.Prefix)
+ var prefix string
+ if params.Prefix != "" {
+ encodedPrefix := params.Prefix
+ decodedPrefix, err := base64.StdEncoding.DecodeString(encodedPrefix)
+ if err != nil {
+ return nil, prepareError(err)
+ }
+ prefix = string(decodedPrefix)
+ }
+ s3Client, err := newS3BucketClient(session, params.BucketName, prefix)
if err != nil {
return nil, prepareError(err)
}
@@ -465,7 +492,12 @@ func getUploadObjectResponse(session *models.Principal, params user_api.PostBuck
func uploadFiles(ctx context.Context, client MinioClient, params user_api.PostBucketsBucketNameObjectsUploadParams) error {
var prefix string
if params.Prefix != nil {
- prefix = *params.Prefix
+ encodedPrefix := *params.Prefix
+ decodedPrefix, err := base64.StdEncoding.DecodeString(encodedPrefix)
+ if err != nil {
+ return err
+ }
+ prefix = string(decodedPrefix)
}
// parse a request body as multipart/form-data.
@@ -507,7 +539,16 @@ func uploadFiles(ctx context.Context, client MinioClient, params user_api.PostBu
// getShareObjectResponse returns a share object url
func getShareObjectResponse(session *models.Principal, params user_api.ShareObjectParams) (*string, *models.Error) {
ctx := context.Background()
- s3Client, err := newS3BucketClient(session, params.BucketName, params.Prefix)
+ var prefix string
+ if params.Prefix != "" {
+ encodedPrefix := params.Prefix
+ decodedPrefix, err := base64.StdEncoding.DecodeString(encodedPrefix)
+ if err != nil {
+ return nil, prepareError(err)
+ }
+ prefix = string(decodedPrefix)
+ }
+ s3Client, err := newS3BucketClient(session, params.BucketName, prefix)
if err != nil {
return nil, prepareError(err)
}
@@ -552,7 +593,16 @@ func getSetObjectLegalHoldResponse(session *models.Principal, params user_api.Pu
// create a minioClient interface implementation
// defining the client to be used
minioClient := minioClient{client: mClient}
- err = setObjectLegalHold(ctx, minioClient, params.BucketName, params.Prefix, params.VersionID, *params.Body.Status)
+ var prefix string
+ if params.Prefix != "" {
+ encodedPrefix := params.Prefix
+ decodedPrefix, err := base64.StdEncoding.DecodeString(encodedPrefix)
+ if err != nil {
+ return prepareError(err)
+ }
+ prefix = string(decodedPrefix)
+ }
+ err = setObjectLegalHold(ctx, minioClient, params.BucketName, prefix, params.VersionID, *params.Body.Status)
if err != nil {
return prepareError(err)
}
@@ -579,7 +629,16 @@ func getSetObjectRetentionResponse(session *models.Principal, params user_api.Pu
// create a minioClient interface implementation
// defining the client to be used
minioClient := minioClient{client: mClient}
- err = setObjectRetention(ctx, minioClient, params.BucketName, params.VersionID, params.Prefix, params.Body)
+ var prefix string
+ if params.Prefix != "" {
+ encodedPrefix := params.Prefix
+ decodedPrefix, err := base64.StdEncoding.DecodeString(encodedPrefix)
+ if err != nil {
+ return prepareError(err)
+ }
+ prefix = string(decodedPrefix)
+ }
+ err = setObjectRetention(ctx, minioClient, params.BucketName, params.VersionID, prefix, params.Body)
if err != nil {
return prepareError(err)
}
@@ -623,7 +682,16 @@ func deleteObjectRetentionResponse(session *models.Principal, params user_api.De
// create a minioClient interface implementation
// defining the client to be used
minioClient := minioClient{client: mClient}
- err = deleteObjectRetention(ctx, minioClient, params.BucketName, params.Prefix, params.VersionID)
+ var prefix string
+ if params.Prefix != "" {
+ encodedPrefix := params.Prefix
+ decodedPrefix, err := base64.StdEncoding.DecodeString(encodedPrefix)
+ if err != nil {
+ return prepareError(err)
+ }
+ prefix = string(decodedPrefix)
+ }
+ err = deleteObjectRetention(ctx, minioClient, params.BucketName, prefix, params.VersionID)
if err != nil {
return prepareError(err)
}
@@ -649,7 +717,16 @@ func getPutObjectTagsResponse(session *models.Principal, params user_api.PutObje
// create a minioClient interface implementation
// defining the client to be used
minioClient := minioClient{client: mClient}
- err = putObjectTags(ctx, minioClient, params.BucketName, params.Prefix, params.VersionID, params.Body.Tags)
+ var prefix string
+ if params.Prefix != "" {
+ encodedPrefix := params.Prefix
+ decodedPrefix, err := base64.StdEncoding.DecodeString(encodedPrefix)
+ if err != nil {
+ return prepareError(err)
+ }
+ prefix = string(decodedPrefix)
+ }
+ err = putObjectTags(ctx, minioClient, params.BucketName, prefix, params.VersionID, params.Body.Tags)
if err != nil {
return prepareError(err)
}
|