diff --git a/chat/handlers/blog.go b/chat/handlers/blog.go
index 1858d6c9e..6a83381d9 100644
--- a/chat/handlers/blog.go
+++ b/chat/handlers/blog.go
@@ -86,7 +86,7 @@ func (h *BlogHandler) getPostsWoUsers(ctx context.Context, blogs []*db.Blog) ([]
query.Set(utils.FileParam, utils.SetImagePreviewExtension(fileParam))
dumbUrl.RawQuery = query.Encode()
- publicPreviewUrl, err := makeUrlPublic(dumbUrl.String(), utils.UrlStorageEmbedPreview, false, post.ChatId, post.MessageId)
+ publicPreviewUrl, err := makeUrlPublic(dumbUrl.String(), utils.UrlStorageEmbedPreview, post.ChatId, post.MessageId)
if err != nil {
h.lgr.WithTracing(ctx).Warnf("Unagle to change url: %v", err)
break
@@ -503,7 +503,7 @@ func PatchStorageUrlToPublic(ctx context.Context, lgr *logger.Logger, text strin
original, originalExists := maybeImage.Attr("data-original")
if originalExists { // we have 2 tags - preview (small, tag attr) and original (data-original attr)
if utils.ContainsUrl(lgr, wlArr, original) { // original
- newurl, err := makeUrlPublic(original, "", false, overrideChatId, overrideMessageId)
+ newurl, err := makeUrlPublic(original, "", overrideChatId, overrideMessageId)
if err != nil {
lgr.WithTracing(ctx).Warnf("Unagle to change url: %v", err)
return
@@ -513,7 +513,7 @@ func PatchStorageUrlToPublic(ctx context.Context, lgr *logger.Logger, text strin
src, srcExists := maybeImage.Attr("src") // preview
if srcExists && utils.ContainsUrl(lgr, wlArr, src) {
- newurl, err := makeUrlPublic(src, utils.UrlStorageEmbedPreview, false, overrideChatId, overrideMessageId)
+ newurl, err := makeUrlPublic(src, utils.UrlStorageEmbedPreview, overrideChatId, overrideMessageId)
if err != nil {
lgr.WithTracing(ctx).Warnf("Unagle to change url: %v", err)
return
@@ -544,7 +544,8 @@ func (h *BlogHandler) getFileParam(src string) (string, error) {
const OverrideMessageId = "overrideMessageId"
const OverrideChatId = "overrideChatId"
-func makeUrlPublic(src string, additionalSegment string, addTime bool, overrideChatId, overrideMessageId int64) (string, error) {
+// see also storage/services/files.go :: makeUrlPublic
+func makeUrlPublic(src string, additionalSegment string, overrideChatId, overrideMessageId int64) (string, error) {
if strings.HasPrefix(src, "/api/storage/assets/") { // don't touch built-in default urls (used for video-by-link, audio)
return src, nil
}
@@ -555,14 +556,10 @@ func makeUrlPublic(src string, additionalSegment string, addTime bool, overrideC
return "", err
}
- parsed.Path = utils.UrlApiPrefix + utils.UrlStoragePublicGetFile + additionalSegment
+ parsed.Path = utils.UrlStoragePublicGetFile + additionalSegment
query := parsed.Query()
- if addTime {
- addTimeToUrlValues(&query)
- }
-
query.Set(OverrideMessageId, utils.Int64ToString(overrideMessageId))
query.Set(OverrideChatId, utils.Int64ToString(overrideChatId))
diff --git a/chat/utils/utils.go b/chat/utils/utils.go
index a43128a82..8ef674b67 100644
--- a/chat/utils/utils.go
+++ b/chat/utils/utils.go
@@ -225,8 +225,7 @@ func Min(a, b int) int {
}
const FileParam = "file"
-const UrlApiPrefix = "/api"
-const UrlStoragePublicGetFile = "/storage/public/download"
+const UrlStoragePublicGetFile = "/api/storage/public/download"
const UrlStorageEmbedPreview = "/embed/preview"
func SetImagePreviewExtension(key string) string {
diff --git a/event/dto/rabbitmq.go b/event/dto/rabbitmq.go
index 117af14ff..c3cceb018 100644
--- a/event/dto/rabbitmq.go
+++ b/event/dto/rabbitmq.go
@@ -140,7 +140,7 @@ type FileInfoDto struct {
Id string `json:"id"`
Filename string `json:"filename"`
Url string `json:"url"`
- PublicUrl *string `json:"publicUrl"`
+ PublishedUrl *string `json:"publishedUrl"`
PreviewUrl *string `json:"previewUrl"`
Size int64 `json:"size"`
CanDelete bool `json:"canDelete"`
diff --git a/event/graph/generated.go b/event/graph/generated.go
index a42c7d503..f08550ae4 100644
--- a/event/graph/generated.go
+++ b/event/graph/generated.go
@@ -174,7 +174,7 @@ type ComplexityRoot struct {
Owner func(childComplexity int) int
OwnerID func(childComplexity int) int
PreviewURL func(childComplexity int) int
- PublicURL func(childComplexity int) int
+ PublishedURL func(childComplexity int) int
Size func(childComplexity int) int
URL func(childComplexity int) int
}
@@ -1120,12 +1120,12 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in
return e.complexity.FileInfoDto.PreviewURL(childComplexity), true
- case "FileInfoDto.publicUrl":
- if e.complexity.FileInfoDto.PublicURL == nil {
+ case "FileInfoDto.publishedUrl":
+ if e.complexity.FileInfoDto.PublishedURL == nil {
break
}
- return e.complexity.FileInfoDto.PublicURL(childComplexity), true
+ return e.complexity.FileInfoDto.PublishedURL(childComplexity), true
case "FileInfoDto.size":
if e.complexity.FileInfoDto.Size == nil {
@@ -6197,8 +6197,8 @@ func (ec *executionContext) fieldContext_FileInfoDto_url(_ context.Context, fiel
return fc, nil
}
-func (ec *executionContext) _FileInfoDto_publicUrl(ctx context.Context, field graphql.CollectedField, obj *model.FileInfoDto) (ret graphql.Marshaler) {
- fc, err := ec.fieldContext_FileInfoDto_publicUrl(ctx, field)
+func (ec *executionContext) _FileInfoDto_publishedUrl(ctx context.Context, field graphql.CollectedField, obj *model.FileInfoDto) (ret graphql.Marshaler) {
+ fc, err := ec.fieldContext_FileInfoDto_publishedUrl(ctx, field)
if err != nil {
return graphql.Null
}
@@ -6211,7 +6211,7 @@ func (ec *executionContext) _FileInfoDto_publicUrl(ctx context.Context, field gr
}()
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
ctx = rctx // use context from middleware stack in children
- return obj.PublicURL, nil
+ return obj.PublishedURL, nil
})
if err != nil {
ec.Error(ctx, err)
@@ -6225,7 +6225,7 @@ func (ec *executionContext) _FileInfoDto_publicUrl(ctx context.Context, field gr
return ec.marshalOString2áš–string(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_FileInfoDto_publicUrl(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_FileInfoDto_publishedUrl(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "FileInfoDto",
Field: field,
@@ -13113,8 +13113,8 @@ func (ec *executionContext) fieldContext_WrappedFileInfoDto_fileInfoDto(_ contex
return ec.fieldContext_FileInfoDto_filename(ctx, field)
case "url":
return ec.fieldContext_FileInfoDto_url(ctx, field)
- case "publicUrl":
- return ec.fieldContext_FileInfoDto_publicUrl(ctx, field)
+ case "publishedUrl":
+ return ec.fieldContext_FileInfoDto_publishedUrl(ctx, field)
case "previewUrl":
return ec.fieldContext_FileInfoDto_previewUrl(ctx, field)
case "size":
@@ -15725,8 +15725,8 @@ func (ec *executionContext) _FileInfoDto(ctx context.Context, sel ast.SelectionS
if out.Values[i] == graphql.Null {
out.Invalids++
}
- case "publicUrl":
- out.Values[i] = ec._FileInfoDto_publicUrl(ctx, field, obj)
+ case "publishedUrl":
+ out.Values[i] = ec._FileInfoDto_publishedUrl(ctx, field, obj)
case "previewUrl":
out.Values[i] = ec._FileInfoDto_previewUrl(ctx, field, obj)
case "size":
diff --git a/event/graph/model/models_gen.go b/event/graph/model/models_gen.go
index 1210cc8d2..c8d0ddfc3 100644
--- a/event/graph/model/models_gen.go
+++ b/event/graph/model/models_gen.go
@@ -124,7 +124,7 @@ type FileInfoDto struct {
ID string `json:"id"`
Filename string `json:"filename"`
URL string `json:"url"`
- PublicURL *string `json:"publicUrl"`
+ PublishedURL *string `json:"publishedUrl"`
PreviewURL *string `json:"previewUrl"`
Size int64 `json:"size"`
CanDelete bool `json:"canDelete"`
diff --git a/event/graph/schema.graphqls b/event/graph/schema.graphqls
index 2e2a8340a..ec85d0b1f 100644
--- a/event/graph/schema.graphqls
+++ b/event/graph/schema.graphqls
@@ -152,7 +152,7 @@ type FileInfoDto {
id: String!
filename: String!
url: String!
- publicUrl: String
+ publishedUrl: String
previewUrl: String
size: Int64!
canDelete: Boolean!
diff --git a/event/graph/schema.resolvers.go b/event/graph/schema.resolvers.go
index 36311527a..673fef38c 100644
--- a/event/graph/schema.resolvers.go
+++ b/event/graph/schema.resolvers.go
@@ -593,7 +593,7 @@ func convertToChatEvent(e *dto.ChatEvent) *model.ChatEvent {
ID: fileEvent.FileInfoDto.Id,
Filename: fileEvent.FileInfoDto.Filename,
URL: fileEvent.FileInfoDto.Url,
- PublicURL: fileEvent.FileInfoDto.PublicUrl,
+ PublishedURL: fileEvent.FileInfoDto.PublishedUrl,
PreviewURL: fileEvent.FileInfoDto.PreviewUrl,
Size: fileEvent.FileInfoDto.Size,
CanDelete: fileEvent.FileInfoDto.CanDelete,
diff --git a/frontend/src/ChatView.vue b/frontend/src/ChatView.vue
index 8be533bbc..cd2fe960a 100644
--- a/frontend/src/ChatView.vue
+++ b/frontend/src/ChatView.vue
@@ -461,7 +461,7 @@ export default {
id
filename
url
- publicUrl
+ publishedUrl
previewUrl
size
canDelete
diff --git a/frontend/src/FileListContextMenu.vue b/frontend/src/FileListContextMenu.vue
index 64fa913b6..9eed12f59 100644
--- a/frontend/src/FileListContextMenu.vue
+++ b/frontend/src/FileListContextMenu.vue
@@ -104,7 +104,7 @@ export default {
}
if (this.menuableItem.canShare) {
- if (!this.menuableItem.publicUrl) {
+ if (!this.menuableItem.publishedUrl) {
ret.push({
title: this.$vuetify.locale.t('$vuetify.share_file'),
icon: 'mdi-export',
diff --git a/frontend/src/FileListModal.vue b/frontend/src/FileListModal.vue
index 763ed7729..cf668255e 100644
--- a/frontend/src/FileListModal.vue
+++ b/frontend/src/FileListModal.vue
@@ -64,7 +64,7 @@
{{ formattedSize(item.size) }}
{{ $vuetify.locale.t('$vuetify.files_by') }} {{item.owner?.login}}
{{$vuetify.locale.t('$vuetify.time_at')}} {{getDate(item)}}
-
+
{{ $vuetify.locale.t('$vuetify.files_public_url') }}
@@ -85,11 +85,11 @@
mdi-pencil
-
+
mdi-export
-
+
mdi-lock
@@ -306,7 +306,7 @@ export default {
},
shareFile(dto) {
axios.put(`/api/storage/publish/file`, {id: dto.id, public: true}).then((resp)=>{
- const link = resp.data.publicUrl;
+ const link = resp.data.publishedUrl;
if (link) {
navigator.clipboard.writeText(getUrlPrefix() + link);
this.setTempNotification(this.$vuetify.locale.t('$vuetify.published_file_link_copied'));
diff --git a/public/common/components/FileListModal.vue b/public/common/components/FileListModal.vue
index 65c205800..4e73d9764 100644
--- a/public/common/components/FileListModal.vue
+++ b/public/common/components/FileListModal.vue
@@ -64,9 +64,6 @@
{{ formattedSize(item.size) }}
by {{item.owner?.login}}
at {{getDate(item)}}
-
- Public url
-
@@ -174,7 +171,8 @@ export default {
searchString: null,
showSearchButton: true,
markInstance: null,
- chatId: null,
+ chatId: null, // overrideChatId
+ messageId: null, // overrideMessageId
fileUploadingSessionType: null,
correlationId: null,
fileListMode: false,
@@ -283,14 +281,15 @@ export default {
setStoredFileListMode(newValue);
},
hasLength,
- isCachedRelevantToArguments({fileItemUuid, chatId}) {
- return this.fileItemUuid == fileItemUuid && this.chatId == chatId
+ isCachedRelevantToArguments({fileItemUuid, chatId, messageId}) {
+ return this.fileItemUuid == fileItemUuid && this.chatId == chatId && this.messageId == messageId
},
- initializeWithArguments({fileItemUuid, messageEditing, messageIdToDetachFiles, chatId, fileUploadingSessionType, correlationId}) {
+ initializeWithArguments({fileItemUuid, messageEditing, messageIdToDetachFiles, chatId, messageId, fileUploadingSessionType, correlationId}) {
this.messageIdToDetachFiles = messageIdToDetachFiles;
this.isMessageEditing = messageEditing;
this.fileItemUuid = fileItemUuid;
this.chatId = chatId;
+ this.messageId = messageId;
// just pass them to FileUploadModal
this.fileUploadingSessionType = fileUploadingSessionType;
@@ -300,12 +299,14 @@ export default {
// blog post: blogDto.messageId
// public message: messageDto.messageItem.id
// TODO curl -Ss --url 'http://localhost:1236/api/storage/public/1019?overrideChatId=1019&overrideMessageId=1' | jq
- return axios.get(`/api/storage/${this.chatId}`, {
+ return axios.get(`/api/storage/public/${this.chatId}`, {
params: {
page: this.translatePage(),
size: PAGE_SIZE_SMALL,
fileItemUuid : this.fileItemUuid ? this.fileItemUuid : '',
- searchString: this.searchString
+ searchString: this.searchString,
+ overrideChatId: this.chatId,
+ overrideMessageId: this.messageId,
},
})
},
@@ -379,6 +380,7 @@ export default {
},
clearOnReset() {
this.chatId = null;
+ this.messageId = null;
this.fileItemUuid = null;
this.searchString = null;
},
diff --git a/public/pages/blog/post/@id/BlogPost.vue b/public/pages/blog/post/@id/BlogPost.vue
index d6e786ebf..719b4c4b8 100644
--- a/public/pages/blog/post/@id/BlogPost.vue
+++ b/public/pages/blog/post/@id/BlogPost.vue
@@ -142,7 +142,11 @@ export default {
onClickTrap(e)
},
onFilesClicked(item) {
- const obj = {chatId: this.pageContext.data.blogDto.chatId, fileItemUuid : item.fileItemUuid};
+ const obj = {
+ chatId: this.pageContext.data.blogDto.chatId,
+ messageId: item.id,
+ fileItemUuid : item.fileItemUuid
+ };
bus.emit(OPEN_VIEW_FILES_DIALOG, obj);
},
},
diff --git a/storage/config/config-dev/config.yml b/storage/config/config-dev/config.yml
index 1c904e929..a40a83f03 100644
--- a/storage/config/config-dev/config.yml
+++ b/storage/config/config-dev/config.yml
@@ -49,9 +49,9 @@ minio:
secured: false
internalEndpoint: 127.0.0.1:39000
interContainerUrl: http://minio:9000
- publicUrlPrefix: /api/s3
- publicDownloadTtl: 24h
- publicUploadTtl: 24h
+ externalS3UrlPrefix: /api/s3
+ presignDownloadTtl: 24h
+ presignUploadTtl: 24h
accessKeyId: AKIAIOSFODNN7EXAMPLE
secretAccessKey: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
location: "europe-east"
diff --git a/storage/dto/files.go b/storage/dto/files.go
index a85b239e2..61ffd4c78 100644
--- a/storage/dto/files.go
+++ b/storage/dto/files.go
@@ -8,7 +8,7 @@ type FileInfoDto struct {
Id string `json:"id"`
Filename string `json:"filename"`
Url string `json:"url"`
- PublicUrl *string `json:"publicUrl"`
+ PublishedUrl *string `json:"publishedUrl"`
PreviewUrl *string `json:"previewUrl"`
Size int64 `json:"size"`
CanDelete bool `json:"canDelete"`
@@ -20,8 +20,8 @@ type FileInfoDto struct {
CanPlayAsVideo bool `json:"canPlayAsVideo"`
CanShowAsImage bool `json:"canShowAsImage"`
CanPlayAsAudio bool `json:"canPlayAsAudio"`
- FileItemUuid string `json:"fileItemUuid"`
- CorrelationId *string `json:"correlationId"`
+ FileItemUuid string `json:"fileItemUuid"`
+ CorrelationId *string `json:"correlationId"`
}
type WrappedFileInfoDto struct {
diff --git a/storage/handlers/files.go b/storage/handlers/files.go
index 8f3e68277..99ce69824 100644
--- a/storage/handlers/files.go
+++ b/storage/handlers/files.go
@@ -175,7 +175,7 @@ func (h *FilesHandler) InitMultipartUpload(c echo.Context) error {
return err
}
- uploadDuration := viper.GetDuration("minio.publicUploadTtl")
+ uploadDuration := viper.GetDuration("minio.presignUploadTtl")
chunkSize := viper.GetInt64("minio.multipart.chunkSize")
chunksNum := int(reqDto.FileSize / chunkSize)
@@ -367,6 +367,14 @@ func getFileItemUuid(fileId string) string {
}
func (h *FilesHandler) ListHandler(c echo.Context) error {
+ return h.listHandler(c, false)
+}
+
+func (h *FilesHandler) ListHandlerPublic(c echo.Context) error {
+ return h.listHandler(c, true)
+}
+
+func (h *FilesHandler) listHandler(c echo.Context, public bool) error {
var userPrincipalDto, _ = c.Get(utils.USER_PRINCIPAL_DTO).(*auth.AuthResult)
chatId, err := utils.ParseInt64(c.Param("chatId"))
@@ -375,9 +383,14 @@ func (h *FilesHandler) ListHandler(c echo.Context) error {
}
var userId *int64
- if userPrincipalDto != nil {
- userId = &userPrincipalDto.UserId
+ if !public {
+ if userPrincipalDto == nil {
+ return c.NoContent(http.StatusUnauthorized)
+ } else {
+ userId = &userPrincipalDto.UserId
+ }
}
+ // else userPrincipalDto == nil and userId == nil
fileItemUuid := c.QueryParam("fileItemUuid")
@@ -406,7 +419,7 @@ func (h *FilesHandler) ListHandler(c echo.Context) error {
filter := h.getFilterFunction(searchString)
- list, count, err := h.filesService.GetListFilesInFileItem(c.Request().Context(), userId, bucketName, filenameChatPrefix, chatId, filter, true, filesSize, filesOffset)
+ list, count, err := h.filesService.GetListFilesInFileItem(c.Request().Context(), public, overrideChatId, overrideMessageId, userId, bucketName, filenameChatPrefix, chatId, filter, true, filesSize, filesOffset)
if err != nil {
return err
}
@@ -865,13 +878,13 @@ func (h *FilesHandler) SetPublic(c echo.Context) error {
return c.NoContent(http.StatusInternalServerError)
}
- publicUrl, err := h.filesService.GetPublicUrl(bindTo.Public, objectInfo.Key)
+ publishedUrl, err := h.filesService.GetPublishedUrl(bindTo.Public, objectInfo.Key)
if err != nil {
h.lgr.WithTracing(c.Request().Context()).Errorf("Error get public url: %v", err)
return err
}
- return c.JSON(http.StatusOK, &utils.H{"status": "ok", "publicUrl": publicUrl})
+ return c.JSON(http.StatusOK, &utils.H{"status": "ok", "publishedUrl": publishedUrl})
}
type CountResponse struct {
@@ -1144,7 +1157,7 @@ func (h *FilesHandler) ListCandidatesForEmbed(c echo.Context) error {
filter := h.getFilterByType(requestedMediaType)
- items, count, err := h.filesService.GetListFilesInFileItem(c.Request().Context(), &userPrincipalDto.UserId, bucketName, filenameChatPrefix, chatId, filter, false, filesSize, filesOffset)
+ items, count, err := h.filesService.GetListFilesInFileItem(c.Request().Context(), false, utils.ChatIdNonExistent, utils.MessageIdNonExistent, &userPrincipalDto.UserId, bucketName, filenameChatPrefix, chatId, filter, false, filesSize, filesOffset)
if err != nil {
return err
}
@@ -1187,7 +1200,7 @@ func (h *FilesHandler) CountEmbed(c echo.Context) error {
filter := h.getFilterByType(requestedMediaType)
- _, count, err := h.filesService.GetListFilesInFileItem(c.Request().Context(), &userPrincipalDto.UserId, bucketName, filenameChatPrefix, chatId, filter, false, 10, 0)
+ _, count, err := h.filesService.GetListFilesInFileItem(c.Request().Context(), false, utils.ChatIdNonExistent, utils.MessageIdNonExistent, &userPrincipalDto.UserId, bucketName, filenameChatPrefix, chatId, filter, false, 10, 0)
if err != nil {
return err
}
diff --git a/storage/main.go b/storage/main.go
index 03b09a031..277573e6c 100644
--- a/storage/main.go
+++ b/storage/main.go
@@ -205,7 +205,7 @@ func configureEcho(
e.PUT("/api/storage/:chatId/upload/finish", fh.FinishMultipartUpload)
e.PUT("/api/storage/:chatId/replace/file", fh.ReplaceHandler)
e.GET("/api/storage/:chatId", fh.ListHandler)
- e.GET("/api/storage/public/:chatId", fh.ListHandler)
+ e.GET("/api/storage/public/:chatId", fh.ListHandlerPublic)
e.POST("/api/storage/view/list", fh.ViewListHandler)
e.POST("/api/storage/public/view/list", fh.ViewListHandler)
e.POST("/api/storage/view/status", fh.ViewStatusHandler)
diff --git a/storage/services/event.go b/storage/services/event.go
index 507352e18..dd12a8e15 100644
--- a/storage/services/event.go
+++ b/storage/services/event.go
@@ -91,7 +91,7 @@ func (s *EventService) SendToParticipants(ctx context.Context, normalizedKey str
if eventType == utils.FILE_CREATED || eventType == utils.FILE_UPDATED {
if response.objectInfo != nil {
userId := &participantId
- fileInfo, err = s.filesService.GetFileInfo(ctx, userId, *response.objectInfo, chatId, response.tagging, false)
+ fileInfo, err = s.filesService.GetFileInfo(ctx, false, utils.ChatIdNonExistent, utils.MessageIdNonExistent, userId, *response.objectInfo, response.tagging, false)
if err != nil {
s.lgr.WithTracing(ctx).Errorf("Error get file info: %v, skipping", err)
continue
diff --git a/storage/services/files.go b/storage/services/files.go
index 0ae68ad09..a913c4d9c 100644
--- a/storage/services/files.go
+++ b/storage/services/files.go
@@ -40,6 +40,8 @@ func NewFilesService(
func (h *FilesService) GetListFilesInFileItem(
c context.Context,
+ public bool,
+ overrideChatId, overrideMessageId int64,
behalfUserId *int64,
bucket, filenameChatPrefix string,
chatId int64,
@@ -47,6 +49,10 @@ func (h *FilesService) GetListFilesInFileItem(
requestOwners bool,
size, offset int,
) ([]*dto.FileInfoDto, int, error) {
+ if !public && behalfUserId == nil {
+ return nil, 0, errors.New("wrong invariant")
+ }
+
var objects <-chan minio.ObjectInfo = h.minio.ListObjects(c, bucket, minio.ListObjectsOptions{
WithMetadata: true,
Prefix: filenameChatPrefix,
@@ -69,7 +75,7 @@ func (h *FilesService) GetListFilesInFileItem(
continue
}
- info, err := h.GetFileInfo(c, behalfUserId, objInfo, chatId, tagging, true)
+ info, err := h.GetFileInfo(c, public, overrideChatId, overrideMessageId, behalfUserId, objInfo, tagging, true)
if err != nil {
h.lgr.WithTracing(c).Errorf("Error get file info: %v, skipping", err)
continue
@@ -184,7 +190,7 @@ func (h *FilesService) GetCount(ctx context.Context, filenameChatPrefix string)
}
func (h *FilesService) GetTemporaryDownloadUrl(ctx context.Context, aKey string) (string, time.Duration, error) {
- ttl := viper.GetDuration("minio.publicDownloadTtl")
+ ttl := viper.GetDuration("minio.presignDownloadTtl")
u, err := h.minio.PresignedGetObject(ctx, h.minioConfig.Files, aKey, ttl, url.Values{})
if err != nil {
@@ -214,8 +220,8 @@ func (h *FilesService) GetConstantDownloadUrl(aKey string) (string, error) {
}
func ChangeMinioUrl(url *url.URL) (string, error) {
- publicUrlPrefix := viper.GetString("minio.publicUrlPrefix")
- parsed, err := url.Parse(publicUrlPrefix)
+ externalS3UrlPrefix := viper.GetString("minio.externalS3UrlPrefix")
+ parsed, err := url.Parse(externalS3UrlPrefix)
if err != nil {
return "", err
}
@@ -229,7 +235,7 @@ func ChangeMinioUrl(url *url.URL) (string, error) {
return stringV, nil
}
-func (h *FilesService) GetPublicUrl(public bool, fileName string) (*string, error) {
+func (h *FilesService) GetPublishedUrl(public bool, fileName string) (*string, error) {
if !public {
return nil, nil
}
@@ -266,8 +272,10 @@ func (h *FilesService) GetAnonymousPreviewUrl(c context.Context, fileName string
return anUrl, nil
}
-func (h *FilesService) GetFileInfo(c context.Context, behalfUserId *int64, objInfo minio.ObjectInfo, chatId int64, tagging *tags.Tags, hasAmzPrefix bool) (*dto.FileInfoDto, error) {
- previewUrl := h.GetPreviewUrlSmart(c, objInfo.Key)
+func (h *FilesService) GetFileInfo(c context.Context, public bool, overrideChatId, overrideMessageId int64, behalfUserId *int64, objInfo minio.ObjectInfo, tagging *tags.Tags, hasAmzPrefix bool) (*dto.FileInfoDto, error) {
+ if !public && behalfUserId == nil {
+ return nil, errors.New("wrong invariant")
+ }
metadata := objInfo.UserMetadata
@@ -279,21 +287,15 @@ func (h *FilesService) GetFileInfo(c context.Context, behalfUserId *int64, objIn
filename := ReadFilename(objInfo.Key)
- public, err := DeserializeTags(tagging)
+ published, err := DeserializeTags(tagging)
if err != nil {
h.lgr.WithTracing(c).Errorf("Error get tags: %v", err)
return nil, err
}
- publicUrl, err := h.GetPublicUrl(public, objInfo.Key)
+ publishedUrl, err := h.GetPublishedUrl(published, objInfo.Key)
if err != nil {
- h.lgr.WithTracing(c).Errorf("Error get public url: %v", err)
- return nil, err
- }
-
- downloadUrl, err := h.GetConstantDownloadUrl(objInfo.Key)
- if err != nil {
- h.lgr.WithTracing(c).Errorf("Error during getting downlad url %v", err)
+ h.lgr.WithTracing(c).Errorf("Error get published url: %v", err)
return nil, err
}
@@ -306,11 +308,44 @@ func (h *FilesService) GetFileInfo(c context.Context, behalfUserId *int64, objIn
theCorrelationId = &correlationId
}
+ var downloadUrl string
+ var previewUrl *string
+
var canDelete, canEdit, canShare bool
- if behalfUserId != nil {
+
+ downloadUrltmp, err := h.GetConstantDownloadUrl(objInfo.Key)
+ if err != nil {
+ h.lgr.WithTracing(c).Errorf("Error during getting downlad url %v", err)
+ return nil, err
+ }
+
+ previewUrltmp := h.GetPreviewUrlSmart(c, objInfo.Key)
+
+ if !public {
+ // normal flow
canDelete = fileOwnerId == *behalfUserId
canEdit = fileOwnerId == *behalfUserId && utils.IsPlainText(objInfo.Key)
canShare = fileOwnerId == *behalfUserId
+
+ downloadUrl = downloadUrltmp
+ previewUrl = previewUrltmp
+ } else {
+ // public microservice flow - user clicks on FileListModal
+ // it's safe becasue we already checked the access before
+ downloadUrl, err = makeUrlPublic(downloadUrltmp, "", overrideChatId, overrideMessageId)
+ if err != nil {
+ h.lgr.WithTracing(c).Errorf("Error during getting downlad url %v", err)
+ return nil, err
+ }
+
+ if previewUrltmp != nil {
+ previewUrlpublic, err := makeUrlPublic(*previewUrltmp, utils.UrlStorageEmbedPreview, overrideChatId, overrideMessageId)
+ if err != nil {
+ h.lgr.WithTracing(c).Errorf("Error during getting downlad url %v", err)
+ return nil, err
+ }
+ previewUrl = &previewUrlpublic
+ }
}
info := &dto.FileInfoDto{
@@ -323,7 +358,7 @@ func (h *FilesService) GetFileInfo(c context.Context, behalfUserId *int64, objIn
CanShare: canShare,
LastModified: objInfo.LastModified,
OwnerId: fileOwnerId,
- PublicUrl: publicUrl,
+ PublishedUrl: publishedUrl,
PreviewUrl: previewUrl,
CanPlayAsVideo: utils.IsVideo(objInfo.Key),
CanShowAsImage: utils.IsImage(objInfo.Key),
@@ -334,6 +369,33 @@ func (h *FilesService) GetFileInfo(c context.Context, behalfUserId *int64, objIn
return info, nil
}
+// prepares url to use ib lublic microservice
+// in case getting file list
+// see also chat/handlers/blog.go :: makeUrlPublic
+func makeUrlPublic(src string, additionalSegment string, overrideChatId, overrideMessageId int64) (string, error) {
+ if strings.HasPrefix(src, "/api/storage/assets/") { // don't touch built-in default urls (used for video-by-link, audio)
+ return src, nil
+ }
+
+ // we add time in order not to cache the video itself
+ parsed, err := url.Parse(src)
+ if err != nil {
+ return "", err
+ }
+
+ parsed.Path = utils.UrlStoragePublicGetFile + additionalSegment
+
+ query := parsed.Query()
+
+ query.Set(utils.OverrideMessageId, utils.Int64ToString(overrideMessageId))
+ query.Set(utils.OverrideChatId, utils.Int64ToString(overrideChatId))
+
+ parsed.RawQuery = query.Encode()
+
+ newurl := parsed.String()
+ return newurl, nil
+}
+
const Media_image = "image"
const Media_video = "video"
const Media_audio = "audio"
@@ -410,7 +472,7 @@ func (h *FilesService) getPreviewUrl(c context.Context, aKey string, requestedMe
return previewUrl
}
-const publicKey = "public"
+const publishedKey = "published"
const ownerIdKey = "ownerid"
const chatIdKey = "chatid"
@@ -545,9 +607,9 @@ func MessageRecordingKey(hasAmzPrefix bool) string {
return prefix + strings.Title(messageRecordingKey)
}
-func SerializeTags(public bool) map[string]string {
+func SerializeTags(published bool) map[string]string {
var userTags = map[string]string{}
- userTags[publicKey] = fmt.Sprintf("%v", public)
+ userTags[publishedKey] = fmt.Sprintf("%v", published)
return userTags
}
@@ -557,11 +619,11 @@ func DeserializeTags(tagging *tags.Tags) (bool, error) {
}
var tagsMap map[string]string = tagging.ToMap()
- publicString, ok := tagsMap[publicKey]
+ publishedString, ok := tagsMap[publishedKey]
if !ok {
return false, nil
}
- return utils.ParseBoolean(publicString)
+ return utils.ParseBoolean(publishedString)
}
func GetUsersRemotelyOrEmpty(lgr *logger.Logger, userIdSet map[int64]bool, restClient *client.RestClient, c context.Context) map[int64]*dto.User {
diff --git a/storage/utils/utils.go b/storage/utils/utils.go
index 09cf7d667..e3d740252 100644
--- a/storage/utils/utils.go
+++ b/storage/utils/utils.go
@@ -294,6 +294,7 @@ const UrlStoragePublicPreviewFile = "/api/storage/public/download/embed/preview"
const UrlStorageGetFile = "/api/storage/download"
const UrlStorageGetFilePublicExternal = "/api/storage/public/download"
const UrlBasePreview = "/api/storage/embed/preview"
+const UrlStorageEmbedPreview = "/embed/preview"
const UrlBasePublicPreview = "/api/storage/public/download/embed/preview"
// returns monotonically decreasing lexically sequence to use S3's lexical sorting