mirror of
https://github.com/hay-kot/homebox.git
synced 2025-08-06 01:20:31 +00:00
implement attachment token access
This commit is contained in:
parent
323fd919d1
commit
9a671dc483
4 changed files with 55 additions and 41 deletions
|
@ -13,8 +13,9 @@ import (
|
||||||
|
|
||||||
type (
|
type (
|
||||||
TokenResponse struct {
|
TokenResponse struct {
|
||||||
Token string `json:"token"`
|
Token string `json:"token"`
|
||||||
ExpiresAt time.Time `json:"expiresAt"`
|
ExpiresAt time.Time `json:"expiresAt"`
|
||||||
|
AttachmentToken string `json:"attachmentToken"`
|
||||||
}
|
}
|
||||||
|
|
||||||
LoginForm struct {
|
LoginForm struct {
|
||||||
|
@ -76,8 +77,9 @@ func (ctrl *V1Controller) HandleAuthLogin() server.HandlerFunc {
|
||||||
}
|
}
|
||||||
|
|
||||||
return server.Respond(w, http.StatusOK, TokenResponse{
|
return server.Respond(w, http.StatusOK, TokenResponse{
|
||||||
Token: "Bearer " + newToken.Raw,
|
Token: "Bearer " + newToken.Raw,
|
||||||
ExpiresAt: newToken.ExpiresAt,
|
ExpiresAt: newToken.ExpiresAt,
|
||||||
|
AttachmentToken: newToken.AttachmentToken,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -130,7 +130,7 @@ func (ctrl *V1Controller) HandleItemAttachmentDownload() server.HandlerFunc {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// HandleItemAttachmentToken godocs
|
// HandleItemAttachmentGet godocs
|
||||||
// @Summary retrieves an attachment for an item
|
// @Summary retrieves an attachment for an item
|
||||||
// @Tags Items Attachments
|
// @Tags Items Attachments
|
||||||
// @Produce application/octet-stream
|
// @Produce application/octet-stream
|
||||||
|
@ -139,7 +139,7 @@ func (ctrl *V1Controller) HandleItemAttachmentDownload() server.HandlerFunc {
|
||||||
// @Success 200 {object} ItemAttachmentToken
|
// @Success 200 {object} ItemAttachmentToken
|
||||||
// @Router /v1/items/{id}/attachments/{attachment_id} [GET]
|
// @Router /v1/items/{id}/attachments/{attachment_id} [GET]
|
||||||
// @Security Bearer
|
// @Security Bearer
|
||||||
func (ctrl *V1Controller) HandleItemAttachmentToken() server.HandlerFunc {
|
func (ctrl *V1Controller) HandleItemAttachmentGet() server.HandlerFunc {
|
||||||
return ctrl.handleItemAttachmentsHandler
|
return ctrl.handleItemAttachmentsHandler
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -181,33 +181,15 @@ func (ctrl *V1Controller) handleItemAttachmentsHandler(w http.ResponseWriter, r
|
||||||
|
|
||||||
ctx := services.NewContext(r.Context())
|
ctx := services.NewContext(r.Context())
|
||||||
switch r.Method {
|
switch r.Method {
|
||||||
// Token Handler
|
|
||||||
case http.MethodGet:
|
case http.MethodGet:
|
||||||
token, err := ctrl.svc.Items.AttachmentToken(ctx, ID, attachmentID)
|
doc, err := ctrl.svc.Items.AttachmentPathV2(r.Context(), attachmentID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
switch err {
|
log.Err(err).Msg("failed to get attachment path")
|
||||||
case services.ErrNotFound:
|
return validate.NewRequestError(err, http.StatusInternalServerError)
|
||||||
log.Err(err).
|
|
||||||
Str("id", attachmentID.String()).
|
|
||||||
Msg("failed to find attachment with id")
|
|
||||||
|
|
||||||
return validate.NewRequestError(err, http.StatusNotFound)
|
|
||||||
|
|
||||||
case services.ErrFileNotFound:
|
|
||||||
log.Err(err).
|
|
||||||
Str("id", attachmentID.String()).
|
|
||||||
Msg("failed to find file path for attachment with id")
|
|
||||||
log.Warn().Msg("attachment with no file path removed from database")
|
|
||||||
|
|
||||||
return validate.NewRequestError(err, http.StatusNotFound)
|
|
||||||
|
|
||||||
default:
|
|
||||||
log.Err(err).Msg("failed to get attachment")
|
|
||||||
return validate.NewRequestError(err, http.StatusInternalServerError)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return server.Respond(w, http.StatusOK, ItemAttachmentToken{Token: token})
|
http.ServeFile(w, r, doc.Path)
|
||||||
|
return nil
|
||||||
|
|
||||||
// Delete Attachment Handler
|
// Delete Attachment Handler
|
||||||
case http.MethodDelete:
|
case http.MethodDelete:
|
||||||
|
|
|
@ -63,6 +63,15 @@ func (svc *ItemService) AttachmentToken(ctx Context, itemId, attachmentId uuid.U
|
||||||
return token.Raw, nil
|
return token.Raw, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (svc *ItemService) AttachmentPathV2(ctx context.Context, attachmentId uuid.UUID) (*ent.Document, error) {
|
||||||
|
attachment, err := svc.repo.Attachments.Get(ctx, attachmentId)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return attachment.Edges.Document, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (svc *ItemService) AttachmentPath(ctx context.Context, token string) (*ent.Document, error) {
|
func (svc *ItemService) AttachmentPath(ctx context.Context, token string) (*ent.Document, error) {
|
||||||
attachmentId, ok := svc.at.Get(token)
|
attachmentId, ok := svc.at.Get(token)
|
||||||
if !ok {
|
if !ok {
|
||||||
|
|
|
@ -6,6 +6,7 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
|
"github.com/hay-kot/homebox/backend/internal/data/ent/authroles"
|
||||||
"github.com/hay-kot/homebox/backend/internal/data/repo"
|
"github.com/hay-kot/homebox/backend/internal/data/repo"
|
||||||
"github.com/hay-kot/homebox/backend/pkgs/hasher"
|
"github.com/hay-kot/homebox/backend/pkgs/hasher"
|
||||||
"github.com/rs/zerolog/log"
|
"github.com/rs/zerolog/log"
|
||||||
|
@ -30,8 +31,9 @@ type (
|
||||||
Password string `json:"password"`
|
Password string `json:"password"`
|
||||||
}
|
}
|
||||||
UserAuthTokenDetail struct {
|
UserAuthTokenDetail struct {
|
||||||
Raw string `json:"raw"`
|
Raw string `json:"raw"`
|
||||||
ExpiresAt time.Time `json:"expiresAt"`
|
AttachmentToken string `json:"attachmentToken"`
|
||||||
|
ExpiresAt time.Time `json:"expiresAt"`
|
||||||
}
|
}
|
||||||
LoginForm struct {
|
LoginForm struct {
|
||||||
Username string `json:"username"`
|
Username string `json:"username"`
|
||||||
|
@ -131,16 +133,37 @@ func (svc *UserService) UpdateSelf(ctx context.Context, ID uuid.UUID, data repo.
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
// User Authentication
|
// User Authentication
|
||||||
|
|
||||||
func (svc *UserService) createToken(ctx context.Context, userId uuid.UUID) (UserAuthTokenDetail, error) {
|
func (svc *UserService) createSessionToken(ctx context.Context, userId uuid.UUID) (UserAuthTokenDetail, error) {
|
||||||
newToken := hasher.GenerateToken()
|
|
||||||
|
|
||||||
created, err := svc.repos.AuthTokens.CreateToken(ctx, repo.UserAuthTokenCreate{
|
attachmentToken := hasher.GenerateToken()
|
||||||
|
attachmentData := repo.UserAuthTokenCreate{
|
||||||
UserID: userId,
|
UserID: userId,
|
||||||
TokenHash: newToken.Hash,
|
TokenHash: attachmentToken.Hash,
|
||||||
ExpiresAt: time.Now().Add(oneWeek),
|
ExpiresAt: time.Now().Add(oneWeek),
|
||||||
})
|
}
|
||||||
|
|
||||||
return UserAuthTokenDetail{Raw: newToken.Raw, ExpiresAt: created.ExpiresAt}, err
|
_, err := svc.repos.AuthTokens.CreateToken(ctx, attachmentData, authroles.RoleAttachments)
|
||||||
|
if err != nil {
|
||||||
|
return UserAuthTokenDetail{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
userToken := hasher.GenerateToken()
|
||||||
|
data := repo.UserAuthTokenCreate{
|
||||||
|
UserID: userId,
|
||||||
|
TokenHash: userToken.Hash,
|
||||||
|
ExpiresAt: time.Now().Add(oneWeek),
|
||||||
|
}
|
||||||
|
|
||||||
|
created, err := svc.repos.AuthTokens.CreateToken(ctx, data, authroles.RoleUser)
|
||||||
|
if err != nil {
|
||||||
|
return UserAuthTokenDetail{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return UserAuthTokenDetail{
|
||||||
|
Raw: userToken.Raw,
|
||||||
|
ExpiresAt: created.ExpiresAt,
|
||||||
|
AttachmentToken: attachmentToken.Raw,
|
||||||
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (svc *UserService) Login(ctx context.Context, username, password string) (UserAuthTokenDetail, error) {
|
func (svc *UserService) Login(ctx context.Context, username, password string) (UserAuthTokenDetail, error) {
|
||||||
|
@ -156,7 +179,7 @@ func (svc *UserService) Login(ctx context.Context, username, password string) (U
|
||||||
return UserAuthTokenDetail{}, ErrorInvalidLogin
|
return UserAuthTokenDetail{}, ErrorInvalidLogin
|
||||||
}
|
}
|
||||||
|
|
||||||
return svc.createToken(ctx, usr.ID)
|
return svc.createSessionToken(ctx, usr.ID)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (svc *UserService) Logout(ctx context.Context, token string) error {
|
func (svc *UserService) Logout(ctx context.Context, token string) error {
|
||||||
|
@ -174,9 +197,7 @@ func (svc *UserService) RenewToken(ctx context.Context, token string) (UserAuthT
|
||||||
return UserAuthTokenDetail{}, ErrorInvalidToken
|
return UserAuthTokenDetail{}, ErrorInvalidToken
|
||||||
}
|
}
|
||||||
|
|
||||||
newToken, _ := svc.createToken(ctx, dbToken.ID)
|
return svc.createSessionToken(ctx, dbToken.ID)
|
||||||
|
|
||||||
return newToken, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeleteSelf deletes the user that is currently logged based of the provided UUID
|
// DeleteSelf deletes the user that is currently logged based of the provided UUID
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue