@@ -29,3 +29,11 @@ func (r *queryResolver) Files(ctx context.Context, filter *models.FileFilter) ([
|
|||||||
func (r *mutationResolver) UploadFile(ctx context.Context, input *graphcore.FileUploadInput) (*models.File, error) {
|
func (r *mutationResolver) UploadFile(ctx context.Context, input *graphcore.FileUploadInput) (*models.File, error) {
|
||||||
return r.s.Files.Upload(ctx, input.File.File, input.Name, input.Public, input.File.Size)
|
return r.s.Files.Upload(ctx, input.File.File, input.Name, input.Public, input.File.Size)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *mutationResolver) EditFile(ctx context.Context, input *graphcore.FileEditInput) (*models.File, error) {
|
||||||
|
return r.s.Files.Edit(ctx, input.ID, input.Name, input.Public)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *mutationResolver) RemoveFile(ctx context.Context, input *graphcore.FileRemoveInput) (*models.File, error) {
|
||||||
|
return r.s.Files.Remove(ctx, input.ID)
|
||||||
|
}
|
||||||
|
|||||||
@@ -168,6 +168,12 @@ type Mutation {
|
|||||||
|
|
||||||
"Upload a file"
|
"Upload a file"
|
||||||
uploadFile(input: FileUploadInput): File!
|
uploadFile(input: FileUploadInput): File!
|
||||||
|
|
||||||
|
"Edit a file"
|
||||||
|
editFile(input: FileEditInput): File!
|
||||||
|
|
||||||
|
"Remove a file"
|
||||||
|
removeFile(input: FileRemoveInput): File!
|
||||||
}
|
}
|
||||||
|
|
||||||
type Subscription {
|
type Subscription {
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ type Change {
|
|||||||
objects: [ChangeObject!]!
|
objects: [ChangeObject!]!
|
||||||
}
|
}
|
||||||
|
|
||||||
union ChangeObject = Character | Channel | Log | Post | Story | Tag | Chapter | Comment
|
union ChangeObject = Character | Channel | Log | Post | Story | Tag | Chapter | Comment | File
|
||||||
|
|
||||||
"""
|
"""
|
||||||
A change key is a key associated with a change, used for filtering
|
A change key is a key associated with a change, used for filtering
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ input FileUploadInput {
|
|||||||
}
|
}
|
||||||
|
|
||||||
# Input for editFile mutation
|
# Input for editFile mutation
|
||||||
input EditFileInput {
|
input FileEditInput {
|
||||||
# The file's unique ID
|
# The file's unique ID
|
||||||
id: String!
|
id: String!
|
||||||
|
|
||||||
@@ -61,4 +61,10 @@ input EditFileInput {
|
|||||||
|
|
||||||
# The file's name
|
# The file's name
|
||||||
name: String
|
name: String
|
||||||
|
}
|
||||||
|
|
||||||
|
# Input for removeFile mutation
|
||||||
|
input FileRemoveInput {
|
||||||
|
# The file's unique ID
|
||||||
|
id: String!
|
||||||
}
|
}
|
||||||
+47
-8
@@ -11,6 +11,7 @@ import (
|
|||||||
"github.com/h2non/filetype"
|
"github.com/h2non/filetype"
|
||||||
"io"
|
"io"
|
||||||
"log"
|
"log"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -51,10 +52,12 @@ func (s *FileService) List(ctx context.Context, filter models.FileFilter) ([]*mo
|
|||||||
if filter.Public != nil {
|
if filter.Public != nil {
|
||||||
if *filter.Public == false {
|
if *filter.Public == false {
|
||||||
if filter.Author == nil || *filter.Author == "" {
|
if filter.Author == nil || *filter.Author == "" {
|
||||||
return nil, ErrPrivateNoAuthor
|
if token == nil {
|
||||||
}
|
return nil, ErrUnauthorized
|
||||||
|
}
|
||||||
|
|
||||||
if !token.PermittedUser(*filter.Author, "member", "file.list") {
|
filter.Author = &token.UserID
|
||||||
|
} else if !token.PermittedUser(*filter.Author, "member", "file.list") {
|
||||||
return nil, ErrUnauthorized
|
return nil, ErrUnauthorized
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -125,17 +128,53 @@ func (s *FileService) Edit(ctx context.Context, id string, name *string, public
|
|||||||
|
|
||||||
err = s.authService.CheckPermission(ctx, "edit", file)
|
err = s.authService.CheckPermission(ctx, "edit", file)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if !file.Public {
|
|
||||||
return nil, repositories.ErrNotFound
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return s.files.Update(ctx, *file, models.FileUpdate{
|
file, err = s.files.Update(ctx, *file, models.FileUpdate{
|
||||||
Name: name,
|
Name: name,
|
||||||
Public: public,
|
Public: public,
|
||||||
})
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
s.changeService.Submit(ctx, models.ChangeModelFile, "edit", file.Public, changekeys.Listed(file), file)
|
||||||
|
|
||||||
|
return file, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *FileService) Remove(ctx context.Context, id string) (*models.File, error) {
|
||||||
|
file, err := s.files.Find(ctx, id)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = s.authService.CheckPermission(ctx, "remove", file)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if file.Kind == "upload" {
|
||||||
|
split := strings.Split(file.URL, "/")
|
||||||
|
name := split[len(split)-1]
|
||||||
|
|
||||||
|
if strings.HasPrefix(name, "U") {
|
||||||
|
err := s.space.RemoveFile(name)
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("Failed to remove file %s for id %s: %s", name, id, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
err = s.files.Delete(ctx, *file)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
s.changeService.Submit(ctx, models.ChangeModelFile, "remove", file.Public, changekeys.Listed(file), file)
|
||||||
|
|
||||||
|
return file, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// concatReader is a quick and dirty reader for reading the head and the file.
|
// concatReader is a quick and dirty reader for reading the head and the file.
|
||||||
|
|||||||
+2
-2
@@ -395,9 +395,9 @@ func (s *StoryService) RemoveComment(ctx context.Context, comment *models.Commen
|
|||||||
}
|
}
|
||||||
|
|
||||||
if story, err := s.stories.Find(ctx, chapter.StoryID); err == nil {
|
if story, err := s.stories.Find(ctx, chapter.StoryID); err == nil {
|
||||||
s.changeService.Submit(ctx, "Chapter", "remove", story.Listed, changekeys.Many(story, chapter, comment), comment)
|
s.changeService.Submit(ctx, "Comment", "remove", story.Listed, changekeys.Many(story, chapter, comment), comment)
|
||||||
} else {
|
} else {
|
||||||
s.changeService.Submit(ctx, "Chapter", "remove", false, changekeys.Many(models.Story{ID: chapter.StoryID}, chapter, comment), comment)
|
s.changeService.Submit(ctx, "Comment", "remove", false, changekeys.Many(models.Story{ID: chapter.StoryID}, chapter, comment), comment)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
|||||||
+2
-4
@@ -49,10 +49,8 @@ func (client *Client) UploadFile(ctx context.Context, name string, mimeType stri
|
|||||||
}
|
}
|
||||||
|
|
||||||
// RemoveFile removes a file from the space
|
// RemoveFile removes a file from the space
|
||||||
func (client *Client) RemoveFile(folder string, name string) error {
|
func (client *Client) RemoveFile(name string) error {
|
||||||
path := folder + "/" + name
|
return client.s3.RemoveObject(client.bucket, client.spaceRoot+"/"+name)
|
||||||
|
|
||||||
return client.s3.RemoveObject(client.bucket, client.spaceRoot+"/"+path)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// DownloadFile opens a file for download, using the same path format as the UploadFile function. Remember to Close it!
|
// DownloadFile opens a file for download, using the same path format as the UploadFile function. Remember to Close it!
|
||||||
|
|||||||
Reference in New Issue
Block a user