mirror of
https://github.com/hay-kot/homebox.git
synced 2025-08-05 17:10:30 +00:00
implement service context
This commit is contained in:
parent
d19f0e2922
commit
0899217c43
3 changed files with 64 additions and 8 deletions
|
@ -3,6 +3,7 @@ package services
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
|
"github.com/google/uuid"
|
||||||
"github.com/hay-kot/homebox/backend/internal/types"
|
"github.com/hay-kot/homebox/backend/internal/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -15,6 +16,31 @@ var (
|
||||||
ContextUserToken = &contextKeys{name: "UserToken"}
|
ContextUserToken = &contextKeys{name: "UserToken"}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type ServiceContext struct {
|
||||||
|
context.Context
|
||||||
|
|
||||||
|
// UID is a unique identifier for the acting user.
|
||||||
|
UID uuid.UUID
|
||||||
|
|
||||||
|
// GID is a unique identifier for the acting users group.
|
||||||
|
GID uuid.UUID
|
||||||
|
|
||||||
|
// User is the acting user.
|
||||||
|
User *types.UserOut
|
||||||
|
}
|
||||||
|
|
||||||
|
// UseServiceCtx is a helper function that returns the service context from the context.
|
||||||
|
// This extracts the users from the context and embeds it into the ServiceContext struct
|
||||||
|
func NewServiceContext(ctx context.Context) ServiceContext {
|
||||||
|
user := UseUserCtx(ctx)
|
||||||
|
return ServiceContext{
|
||||||
|
Context: ctx,
|
||||||
|
UID: user.ID,
|
||||||
|
GID: user.GroupID,
|
||||||
|
User: user,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// SetUserCtx is a helper function that sets the ContextUser and ContextUserToken
|
// SetUserCtx is a helper function that sets the ContextUser and ContextUserToken
|
||||||
// values within the context of a web request (or any context).
|
// values within the context of a web request (or any context).
|
||||||
func SetUserCtx(ctx context.Context, user *types.UserOut, token string) context.Context {
|
func SetUserCtx(ctx context.Context, user *types.UserOut, token string) context.Context {
|
||||||
|
|
|
@ -40,12 +40,12 @@ func (at attachmentTokens) Delete(token string) {
|
||||||
delete(at, token)
|
delete(at, token)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (svc *ItemService) AttachmentToken(ctx context.Context, gid, itemId, attachmentId uuid.UUID) (string, error) {
|
func (svc *ItemService) AttachmentToken(ctx ServiceContext, itemId, attachmentId uuid.UUID) (string, error) {
|
||||||
item, err := svc.repo.Items.GetOne(ctx, itemId)
|
item, err := svc.repo.Items.GetOne(ctx, itemId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
if item.Edges.Group.ID != gid {
|
if item.Edges.Group.ID != ctx.GID {
|
||||||
return "", ErrNotOwner
|
return "", ErrNotOwner
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -77,25 +77,55 @@ func (svc *ItemService) AttachmentPath(ctx context.Context, token string) (strin
|
||||||
return attachment.Edges.Document.Path, nil
|
return attachment.Edges.Document.Path, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (svc *ItemService) AttachmentUpdate(ctx ServiceContext, itemId uuid.UUID, data *types.ItemAttachmentUpdate) (*types.ItemOut, error) {
|
||||||
|
// Update Properties
|
||||||
|
attachment, err := svc.repo.Attachments.Update(ctx, data.ID, attachment.Type(data.Type))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
attDoc := attachment.Edges.Document
|
||||||
|
|
||||||
|
if data.Title != attachment.Edges.Document.Title {
|
||||||
|
newPath := pathlib.Safe(svc.attachmentPath(ctx.GID, itemId, data.Title))
|
||||||
|
|
||||||
|
// Move File
|
||||||
|
err = os.Rename(attachment.Edges.Document.Path, newPath)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = svc.repo.Docs.Update(ctx, attDoc.ID, types.DocumentUpdate{
|
||||||
|
Title: data.Title,
|
||||||
|
Path: newPath,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return svc.GetOne(ctx, ctx.GID, itemId)
|
||||||
|
}
|
||||||
|
|
||||||
// AttachmentAdd adds an attachment to an item by creating an entry in the Documents table and linking it to the Attachment
|
// AttachmentAdd adds an attachment to an item by creating an entry in the Documents table and linking it to the Attachment
|
||||||
// Table and Items table. The file provided via the reader is stored on the file system based on the provided
|
// Table and Items table. The file provided via the reader is stored on the file system based on the provided
|
||||||
// relative path during construction of the service.
|
// relative path during construction of the service.
|
||||||
func (svc *ItemService) AttachmentAdd(ctx context.Context, gid, itemId uuid.UUID, filename string, attachmentType attachment.Type, file io.Reader) (*types.ItemOut, error) {
|
func (svc *ItemService) AttachmentAdd(ctx ServiceContext, itemId uuid.UUID, filename string, attachmentType attachment.Type, file io.Reader) (*types.ItemOut, error) {
|
||||||
// Get the Item
|
// Get the Item
|
||||||
item, err := svc.repo.Items.GetOne(ctx, itemId)
|
item, err := svc.repo.Items.GetOne(ctx, itemId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if item.Edges.Group.ID != gid {
|
if item.Edges.Group.ID != ctx.GID {
|
||||||
return nil, ErrNotOwner
|
return nil, ErrNotOwner
|
||||||
}
|
}
|
||||||
|
|
||||||
fp := svc.attachmentPath(gid, itemId, filename)
|
fp := svc.attachmentPath(ctx.GID, itemId, filename)
|
||||||
filename = filepath.Base(fp)
|
filename = filepath.Base(fp)
|
||||||
|
|
||||||
// Create the document
|
// Create the document
|
||||||
doc, err := svc.repo.Docs.Create(ctx, gid, types.DocumentCreate{
|
doc, err := svc.repo.Docs.Create(ctx, ctx.GID, types.DocumentCreate{
|
||||||
Title: filename,
|
Title: filename,
|
||||||
Path: fp,
|
Path: fp,
|
||||||
})
|
})
|
||||||
|
@ -126,7 +156,7 @@ func (svc *ItemService) AttachmentAdd(ctx context.Context, gid, itemId uuid.UUID
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return svc.GetOne(ctx, gid, itemId)
|
return svc.GetOne(ctx, ctx.GID, itemId)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (svc *ItemService) AttachmentDelete(ctx context.Context, gid, itemId, attachmentId uuid.UUID) error {
|
func (svc *ItemService) AttachmentDelete(ctx context.Context, gid, itemId, attachmentId uuid.UUID) error {
|
||||||
|
|
|
@ -125,7 +125,7 @@ func TestItemService_AddAttachment(t *testing.T) {
|
||||||
reader := strings.NewReader(contents)
|
reader := strings.NewReader(contents)
|
||||||
|
|
||||||
// Setup
|
// Setup
|
||||||
afterAttachment, err := svc.AttachmentAdd(context.Background(), tGroup.ID, itm.ID, "testfile.txt", "attachment", reader)
|
afterAttachment, err := svc.AttachmentAdd(ServiceContext{Context: context.Background(), GID: tGroup.ID}, itm.ID, "testfile.txt", "attachment", reader)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.NotNil(t, afterAttachment)
|
assert.NotNil(t, afterAttachment)
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue