diff --git a/graph2/resolvers/file.go b/graph2/resolvers/file.go index 9cbc8f3..a140eb2 100644 --- a/graph2/resolvers/file.go +++ b/graph2/resolvers/file.go @@ -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) { 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) +} diff --git a/graph2/schema/root.gql b/graph2/schema/root.gql index 3c5e467..4f660dd 100644 --- a/graph2/schema/root.gql +++ b/graph2/schema/root.gql @@ -168,6 +168,12 @@ type Mutation { "Upload a file" uploadFile(input: FileUploadInput): File! + + "Edit a file" + editFile(input: FileEditInput): File! + + "Remove a file" + removeFile(input: FileRemoveInput): File! } type Subscription { diff --git a/graph2/schema/types/Change.gql b/graph2/schema/types/Change.gql index 01012a6..0ea715c 100644 --- a/graph2/schema/types/Change.gql +++ b/graph2/schema/types/Change.gql @@ -27,7 +27,7 @@ type Change { 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 diff --git a/graph2/schema/types/File.gql b/graph2/schema/types/File.gql index 0932e7d..98893c6 100644 --- a/graph2/schema/types/File.gql +++ b/graph2/schema/types/File.gql @@ -51,7 +51,7 @@ input FileUploadInput { } # Input for editFile mutation -input EditFileInput { +input FileEditInput { # The file's unique ID id: String! @@ -61,4 +61,10 @@ input EditFileInput { # The file's name name: String +} + +# Input for removeFile mutation +input FileRemoveInput { + # The file's unique ID + id: String! } \ No newline at end of file diff --git a/services/files.go b/services/files.go index 93f81f8..62e3750 100644 --- a/services/files.go +++ b/services/files.go @@ -11,6 +11,7 @@ import ( "github.com/h2non/filetype" "io" "log" + "strings" "time" ) @@ -51,10 +52,12 @@ func (s *FileService) List(ctx context.Context, filter models.FileFilter) ([]*mo if filter.Public != nil { if *filter.Public == false { 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 } } @@ -125,17 +128,53 @@ func (s *FileService) Edit(ctx context.Context, id string, name *string, public err = s.authService.CheckPermission(ctx, "edit", file) if err != nil { - if !file.Public { - return nil, repositories.ErrNotFound - } - return nil, err } - return s.files.Update(ctx, *file, models.FileUpdate{ + file, err = s.files.Update(ctx, *file, models.FileUpdate{ Name: name, 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. diff --git a/services/stories.go b/services/stories.go index 9bfd2cd..0f939f1 100644 --- a/services/stories.go +++ b/services/stories.go @@ -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 { - 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 { - 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 diff --git a/space/space.go b/space/space.go index 805eca8..a9e1251 100644 --- a/space/space.go +++ b/space/space.go @@ -49,10 +49,8 @@ func (client *Client) UploadFile(ctx context.Context, name string, mimeType stri } // RemoveFile removes a file from the space -func (client *Client) RemoveFile(folder string, name string) error { - path := folder + "/" + name - - return client.s3.RemoveObject(client.bucket, client.spaceRoot+"/"+path) +func (client *Client) RemoveFile(name string) error { + return client.s3.RemoveObject(client.bucket, client.spaceRoot+"/"+name) } // DownloadFile opens a file for download, using the same path format as the UploadFile function. Remember to Close it!