diff --git a/packages/config/config.go b/packages/config/config.go index ea45354..a120a9e 100644 --- a/packages/config/config.go +++ b/packages/config/config.go @@ -10,31 +10,35 @@ import ( ) var ( - Port uint32 = 8080 - MaxDirectMsgCache uint32 = 32 - MaxHubChannelMsgCache uint32 = 16 - FileStorageBucketName string = "communicator" - MaxRequestBytes uint32 = 4 << 10 - MaxRequestWithFileBytes uint32 = 1 << 30 - MaxRequestWithAvatarBytes uint32 = 1 << 20 - MaxRequestWithProfileBgBytes uint32 = 4 << 20 - FileProcessingPartBytes uint64 = 12 << 20 - FileProcessingThreads uint = 3 - FileDownloadLinkTtl time.Duration = 24 * time.Hour + Port uint32 = 8080 + MaxDirectMsgCache uint32 = 32 + MaxHubChannelMsgCache uint32 = 16 + FileStorageBucketName string = "communicator" + MaxRequestBytes uint32 = 4 << 10 + MaxRequestWithFileBytes uint32 = 1 << 30 + MaxRequestWithAvatarBytes uint32 = 1 << 20 + MaxRequestWithProfileBgBytes uint32 = 4 << 20 + MaxRequestWithHubIconBytes uint32 = 1 << 20 + MaxRequestWithHubBackgroundBytes uint32 = 10 << 20 + FileProcessingPartBytes uint64 = 12 << 20 + FileProcessingThreads uint = 3 + FileDownloadLinkTtl time.Duration = 24 * time.Hour ) type configFile struct { - Port uint32 `toml:"port"` - MaxDirectMsgCache uint32 `toml:"max_direct_messages_cache"` - MaxHubChannelMsgCache uint32 `toml:"max_hub_channel_msg_cache"` - MaxRequestBytes uint32 `toml:"max_request_bytes"` - MaxRequestWithFileBytes uint32 `toml:"max_request_with_file_bytes"` - MaxRequestWithAvatarBytes uint32 `toml:"max_request_with_avatar_bytes"` - MaxRequestWithProfileBgBytes uint32 `toml:"max_request_with_profile_bg_bytes"` - FileProcessingPartBytes uint64 `toml:"file_processing_part_bytes"` - FileProcessingThreads uint `toml:"file_processing_threads"` - FileStorageBucketName string `toml:"file_storage_bucket_name"` - FileDownloadLinkTtl time.Duration `toml:"file_download_link_ttl"` + Port uint32 `toml:"port"` + MaxDirectMsgCache uint32 `toml:"max_direct_messages_cache"` + MaxHubChannelMsgCache uint32 `toml:"max_hub_channel_msg_cache"` + MaxRequestBytes uint32 `toml:"max_request_bytes"` + MaxRequestWithFileBytes uint32 `toml:"max_request_with_file_bytes"` + MaxRequestWithAvatarBytes uint32 `toml:"max_request_with_avatar_bytes"` + MaxRequestWithProfileBgBytes uint32 `toml:"max_request_with_profile_bg_bytes"` + MaxRequestWithHubIconBytes uint32 `toml:"max_request_with_hub_icon_bytes"` + MaxRequestWithHubBackgroundBytes uint32 `toml:"max_request_with_hub_background_bytes"` + FileProcessingPartBytes uint64 `toml:"file_processing_part_bytes"` + FileProcessingThreads uint `toml:"file_processing_threads"` + FileStorageBucketName string `toml:"file_storage_bucket_name"` + FileDownloadLinkTtl time.Duration `toml:"file_download_link_ttl"` } func LoadConfFile() { diff --git a/packages/httpRequest/helper.go b/packages/httpRequest/helper.go index 93e2e5d..fc3f78b 100644 --- a/packages/httpRequest/helper.go +++ b/packages/httpRequest/helper.go @@ -15,6 +15,8 @@ const ( file avatar profileBg + hubIcon + hubBackground ) func validCheckWithResponseOnFail(response http.ResponseWriter, request *http.Request, pt bodyLimit) bool { @@ -22,10 +24,19 @@ func validCheckWithResponseOnFail(response http.ResponseWriter, request *http.Re switch pt { case file: maxSize = int64(config.MaxRequestWithFileBytes) + break case avatar: maxSize = int64(config.MaxRequestWithAvatarBytes) + break case profileBg: maxSize = int64(config.MaxRequestWithProfileBgBytes) + break + case hubIcon: + maxSize = int64(config.MaxRequestWithHubIconBytes) + break + case hubBackground: + maxSize = int64(config.MaxRequestWithHubBackgroundBytes) + break default: maxSize = int64(config.MaxRequestBytes) } diff --git a/packages/httpRequest/hubs.go b/packages/httpRequest/hubs.go index 9b575fe..79ab776 100644 --- a/packages/httpRequest/hubs.go +++ b/packages/httpRequest/hubs.go @@ -10,6 +10,7 @@ import ( "go-socket/packages/convertions" "go-socket/packages/cache" + "go-socket/packages/minio" "go-socket/packages/types" "go-socket/packages/wsServer" @@ -466,6 +467,90 @@ func HandleHubSetColor(response http.ResponseWriter, request *http.Request) { response.WriteHeader(http.StatusAccepted) } +func HandleHubSetIcon(response http.ResponseWriter, request *http.Request) { + _, hub, ctx, _, ok := hubPermissionContext(response, request, hubIcon, types.PermissionSetHubIcon) + if !ok { + return + } + + file, header, err := request.FormFile("file") + if err != nil { + http.Error(response, "missing file", http.StatusBadRequest) + return + } + defer file.Close() + + isImg, contentType, err := isImage(file) + if err != nil || !isImg { + http.Error(response, "invalid file", http.StatusBadRequest) + return + } + + key := minio.GetKey(&minio.GetKeyOptions{ + MimeType: contentType, + UploadType: minio.HubIcon, + HubId: hub.Id, + }) + if err = minio.Upload(ctx, key, file, header.Size, contentType, map[string]string{ + "originalName": header.Filename, + }); err != nil { + http.Error(response, "upload failed", http.StatusInternalServerError) + return + } + + if hub.IconUrl != "" { + if err = minio.Delete(ctx, hub.IconUrl); err != nil { + minio.Delete(ctx, key) + http.Error(response, "internal server error", http.StatusInternalServerError) + return + } + } + hub.IconUrl = key + response.WriteHeader(http.StatusCreated) +} + +func HandleHubSetBg(response http.ResponseWriter, request *http.Request) { + _, hub, ctx, _, ok := hubPermissionContext(response, request, hubBackground, types.PermissionSetHubBg) + if !ok { + return + } + + file, header, err := request.FormFile("file") + if err != nil { + http.Error(response, "missing file", http.StatusBadRequest) + return + } + defer file.Close() + + isImg, contentType, err := isImage(file) + if err != nil || !isImg { + http.Error(response, "invalid file", http.StatusBadRequest) + return + } + + key := minio.GetKey(&minio.GetKeyOptions{ + MimeType: contentType, + UploadType: minio.HubBackground, + HubId: hub.Id, + }) + if err = minio.Upload(ctx, key, file, header.Size, contentType, map[string]string{ + "originalName": header.Filename, + }); err != nil { + http.Error(response, "upload failed", http.StatusInternalServerError) + return + } + + if hub.BgUrl != "" { + if err = minio.Delete(ctx, hub.BgUrl); err != nil { + minio.Delete(ctx, key) + http.Error(response, "internal server error", http.StatusInternalServerError) + return + } + } + hub.BgUrl = key + response.WriteHeader(http.StatusCreated) +} + func HandleHubRemove(response http.ResponseWriter, request *http.Request) { _, hub, _, _, ok := hubPermissionContext(response, request, normal, types.PermissionRemoveHub) if !ok { diff --git a/packages/minio/minio.go b/packages/minio/minio.go index 8908323..c5dad4f 100644 --- a/packages/minio/minio.go +++ b/packages/minio/minio.go @@ -24,6 +24,8 @@ const ( HubChannelFile UserAvatar UserProfileBg + HubIcon + HubBackground ) type DataTypePrefix string @@ -33,11 +35,14 @@ const ( HubChannelFilePrefix DataTypePrefix = "hub/" UserAvatarPrefix DataTypePrefix = "userAvatar/" UserProfileBgPrefix DataTypePrefix = "userProfileBg/" + HubIconPrefix DataTypePrefix = "hubIcon/" + HubBackgroundPrefix DataTypePrefix = "hubBackground/" ) type GetKeyOptions struct { UserId uuid.UUID ConnectionId uuid.UUID + HubId uuid.UUID ChannelId uuid.UUID MimeType string UploadType DataType @@ -58,6 +63,10 @@ func GetKey(opts *GetKeyOptions) string { return string(UserAvatarPrefix) + opts.UserId.String() + key case UserProfileBg: return string(UserProfileBgPrefix) + opts.UserId.String() + key + case HubIcon: + return string(HubIconPrefix) + opts.HubId.String() + key + case HubBackground: + return string(HubBackgroundPrefix) + opts.HubId.String() + key default: return string(ConnectionFilePrefix) + opts.ConnectionId.String() + key } diff --git a/todo.txt b/todo.txt index 54c4eb8..b54d371 100644 --- a/todo.txt +++ b/todo.txt @@ -1,6 +1,5 @@ when user not ws connected collect count of unread messages for each conn (add db table in future) -add hubs setting avatar and profilebg check when mutex needed change api endpoints and body/url/header to follow same case