user no stays in cache forever, fix some hubs bugs and add new enpoints
This commit is contained in:
@@ -29,18 +29,12 @@ func HandleAttachmentFileUpload(response http.ResponseWriter, request *http.Requ
|
||||
return
|
||||
}
|
||||
|
||||
request.Body = http.MaxBytesReader(response, request.Body, int64(config.MaxRequestWithFileBytes))
|
||||
|
||||
if err = request.ParseMultipartForm(int64(config.MaxRequestBytes)); err != nil {
|
||||
http.Error(response, "invalid multipart form", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
conn, ok := getConnectionWithResponseOnFail(response, request.FormValue("connectionid"), user)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
target := request.FormValue("target_id")
|
||||
file, header, err := request.FormFile("file")
|
||||
if err != nil {
|
||||
http.Error(response, "missing file", http.StatusBadRequest)
|
||||
@@ -49,11 +43,31 @@ func HandleAttachmentFileUpload(response http.ResponseWriter, request *http.Requ
|
||||
defer file.Close()
|
||||
|
||||
contentType := header.Header.Get("Content-Type")
|
||||
key := minio.GetKey(&minio.GetKeyOptions{
|
||||
ConnectionId: conn.Id,
|
||||
MimeType: contentType,
|
||||
UploadType: minio.ConnectionFile,
|
||||
})
|
||||
var key string
|
||||
|
||||
if conn, ok := getConnection(ctx, target, user); ok {
|
||||
key = minio.GetKey(&minio.GetKeyOptions{
|
||||
ConnectionId: conn.Id,
|
||||
MimeType: contentType,
|
||||
UploadType: minio.ConnectionFile,
|
||||
})
|
||||
} else if channel, ok := getChannelFromUser(user, target); ok {
|
||||
channel.Mu.RLock()
|
||||
perms := channel.UsersCachedPermissions[user.Id]
|
||||
channel.Mu.RUnlock()
|
||||
if !perms.CanMessage() {
|
||||
http.Error(response, "forbidden", http.StatusForbidden)
|
||||
return
|
||||
}
|
||||
key = minio.GetKey(&minio.GetKeyOptions{
|
||||
ChannelId: channel.Id,
|
||||
MimeType: contentType,
|
||||
UploadType: minio.HubChannelFile,
|
||||
})
|
||||
} else {
|
||||
http.Error(response, "cannot find target", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
if err = minio.Upload(ctx, key, file, header.Size, contentType, map[string]string{
|
||||
"originalName": header.Filename,
|
||||
@@ -322,13 +336,27 @@ func HandleAttachmentFileDownload(response http.ResponseWriter, request *http.Re
|
||||
return
|
||||
}
|
||||
|
||||
conn, ok := getConnectionWithResponseOnFail(response, request.FormValue("connectionid"), user)
|
||||
if !ok {
|
||||
target := request.URL.Query().Get("target_id")
|
||||
key := request.URL.Query().Get("key")
|
||||
|
||||
var validPrefix string
|
||||
if conn, ok := getConnection(ctx, target, user); ok {
|
||||
validPrefix = string(minio.ConnectionFilePrefix) + conn.Id.String() + "/"
|
||||
} else if channel, ok := getChannelFromUser(user, target); ok {
|
||||
channel.Mu.RLock()
|
||||
perms := channel.UsersCachedPermissions[user.Id]
|
||||
channel.Mu.RUnlock()
|
||||
if !perms.CanReadHistory() {
|
||||
http.Error(response, "forbidden", http.StatusForbidden)
|
||||
return
|
||||
}
|
||||
validPrefix = string(minio.HubChannelFilePrefix) + channel.Id.String() + "/"
|
||||
} else {
|
||||
http.Error(response, "cannot find target", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
key := request.URL.Query().Get("key")
|
||||
if !strings.HasPrefix(key, string(minio.ConnectionFilePrefix)+conn.Id.String()+"/") {
|
||||
if !strings.HasPrefix(key, validPrefix) {
|
||||
http.Error(response, "no such file", http.StatusUnauthorized)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -36,6 +36,45 @@ func getUserByToken(ctx context.Context, token string) (*types.User, error) {
|
||||
return getUserById(ctx, userId)
|
||||
}
|
||||
|
||||
func getConnection(ctx context.Context, connectionIdStr string, user *types.User) (*types.Connection, bool) {
|
||||
connectionId, err := convertions.StringToUuid(connectionIdStr)
|
||||
if err != nil {
|
||||
return nil, false
|
||||
}
|
||||
if conn, ok := cache.GetConnection(user, connectionId); ok {
|
||||
return conn, true
|
||||
}
|
||||
conn, err := postgresql.ConnectionGetById(ctx, connectionId)
|
||||
if err != nil {
|
||||
return nil, false
|
||||
}
|
||||
if conn.RequestorId != user.Id && conn.RecipientId != user.Id {
|
||||
return nil, false
|
||||
}
|
||||
user.Mu.Lock()
|
||||
user.Connections[conn.Id] = conn
|
||||
user.Mu.Unlock()
|
||||
return conn, true
|
||||
}
|
||||
|
||||
func getChannelFromUser(user *types.User, channelIdStr string) (*types.HubChannel, bool) {
|
||||
channelId, err := convertions.StringToUuid(channelIdStr)
|
||||
if err != nil {
|
||||
return nil, false
|
||||
}
|
||||
user.Mu.RLock()
|
||||
defer user.Mu.RUnlock()
|
||||
for _, hub := range user.Hubs {
|
||||
hub.Mu.RLock()
|
||||
ch, ok := hub.Channels[channelId]
|
||||
hub.Mu.RUnlock()
|
||||
if ok {
|
||||
return ch, true
|
||||
}
|
||||
}
|
||||
return nil, false
|
||||
}
|
||||
|
||||
func getConnectionWithResponseOnFail(response http.ResponseWriter, connectionIdStr string, user *types.User) (*types.Connection, bool) {
|
||||
connectionId, err := convertions.StringToUuid(connectionIdStr)
|
||||
if err != nil {
|
||||
|
||||
@@ -41,6 +41,8 @@ func validCheckWithResponseOnFail(response http.ResponseWriter, request *http.Re
|
||||
maxSize = int64(config.MaxRequestBytes)
|
||||
}
|
||||
|
||||
request.Body = http.MaxBytesReader(response, request.Body, maxSize)
|
||||
|
||||
if request.ContentLength > maxSize {
|
||||
io.Copy(io.Discard, request.Body)
|
||||
http.Error(response, "Request too large", http.StatusRequestEntityTooLarge)
|
||||
|
||||
@@ -551,6 +551,74 @@ func HandleHubSetBg(response http.ResponseWriter, request *http.Request) {
|
||||
response.WriteHeader(http.StatusCreated)
|
||||
}
|
||||
|
||||
func HandleGetHubIcon(response http.ResponseWriter, request *http.Request) {
|
||||
if !validCheckWithResponseOnFail(response, request, normal) {
|
||||
return
|
||||
}
|
||||
ctx := request.Context()
|
||||
_, _, hub, err := getHubUserIfValidWithResponseOnFail(ctx, response, request)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if hub.IconUrl == "" {
|
||||
http.Error(response, "hub has no icon", http.StatusNoContent)
|
||||
return
|
||||
}
|
||||
|
||||
url, meta, err := minio.GetDownloadUrlAndMetadata(ctx, hub.IconUrl)
|
||||
if err != nil {
|
||||
http.Error(response, "internal server error", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
iconData, err := json.Marshal(map[string]any{
|
||||
"url": url.String(),
|
||||
"metadata": meta,
|
||||
})
|
||||
if err != nil {
|
||||
http.Error(response, "json error", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
response.WriteHeader(http.StatusOK)
|
||||
response.Write(iconData)
|
||||
}
|
||||
|
||||
func HandleGetHubBg(response http.ResponseWriter, request *http.Request) {
|
||||
if !validCheckWithResponseOnFail(response, request, normal) {
|
||||
return
|
||||
}
|
||||
ctx := request.Context()
|
||||
_, _, hub, err := getHubUserIfValidWithResponseOnFail(ctx, response, request)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if hub.BgUrl == "" {
|
||||
http.Error(response, "hub has no background", http.StatusNoContent)
|
||||
return
|
||||
}
|
||||
|
||||
url, meta, err := minio.GetDownloadUrlAndMetadata(ctx, hub.BgUrl)
|
||||
if err != nil {
|
||||
http.Error(response, "internal server error", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
bgData, err := json.Marshal(map[string]any{
|
||||
"url": url.String(),
|
||||
"metadata": meta,
|
||||
})
|
||||
if err != nil {
|
||||
http.Error(response, "json error", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
response.WriteHeader(http.StatusOK)
|
||||
response.Write(bgData)
|
||||
}
|
||||
|
||||
func HandleHubRemove(response http.ResponseWriter, request *http.Request) {
|
||||
_, hub, _, _, ok := hubPermissionContext(response, request, normal, types.PermissionRemoveHub)
|
||||
if !ok {
|
||||
@@ -852,7 +920,7 @@ func HandleRoleSetColor(response http.ResponseWriter, request *http.Request) {
|
||||
}
|
||||
color, err := convertions.StringToRgba(request.FormValue("new_color"))
|
||||
if err != nil {
|
||||
http.Error(response, "invalid newcolor", http.StatusBadRequest)
|
||||
http.Error(response, "invalid new_color", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user