1
Fork 0
photoview/api/graphql/resolvers/share_token.go

131 lines
3.8 KiB
Go
Raw Normal View History

2020-02-09 21:25:33 +01:00
package resolvers
import (
"context"
"time"
"github.com/pkg/errors"
"gorm.io/gorm"
2020-12-17 22:29:24 +01:00
"gorm.io/gorm/clause"
2020-12-17 22:51:43 +01:00
api "github.com/photoview/photoview/api/graphql"
"github.com/photoview/photoview/api/graphql/auth"
"github.com/photoview/photoview/api/graphql/models"
2021-04-26 22:35:10 +02:00
"github.com/photoview/photoview/api/graphql/models/actions"
2020-02-09 21:25:33 +01:00
"golang.org/x/crypto/bcrypt"
)
type shareTokenResolver struct {
*Resolver
}
func (r *Resolver) ShareToken() api.ShareTokenResolver {
return &shareTokenResolver{r}
}
2020-12-17 22:29:24 +01:00
func (r *shareTokenResolver) Owner(ctx context.Context, obj *models.ShareToken) (*models.User, error) {
return &obj.Owner, nil
}
2020-11-27 16:02:10 +01:00
2020-12-17 22:29:24 +01:00
func (r *shareTokenResolver) Album(ctx context.Context, obj *models.ShareToken) (*models.Album, error) {
return obj.Album, nil
}
2020-11-27 16:02:10 +01:00
2020-12-17 22:29:24 +01:00
func (r *shareTokenResolver) Media(ctx context.Context, obj *models.ShareToken) (*models.Media, error) {
return obj.Media, nil
}
2020-02-09 21:25:33 +01:00
func (r *shareTokenResolver) HasPassword(ctx context.Context, obj *models.ShareToken) (bool, error) {
hasPassword := obj.Password != nil
return hasPassword, nil
}
func (r *queryResolver) ShareToken(ctx context.Context, credentials models.ShareTokenCredentials) (*models.ShareToken, error) {
2020-02-09 21:25:33 +01:00
2020-11-27 16:02:10 +01:00
var token models.ShareToken
if err := r.DB(ctx).Preload(clause.Associations).Where("value = ?", credentials.Token).First(&token).Error; err != nil {
2020-11-27 16:02:10 +01:00
if errors.Is(err, gorm.ErrRecordNotFound) {
2020-02-11 15:36:12 +01:00
return nil, errors.New("share not found")
2020-02-11 14:32:35 +01:00
} else {
2020-07-10 18:35:37 +02:00
return nil, errors.Wrap(err, "failed to get share token from database")
2020-02-11 14:32:35 +01:00
}
}
2020-06-14 20:56:48 +02:00
if token.Password != nil {
if err := bcrypt.CompareHashAndPassword([]byte(*token.Password), []byte(*credentials.Password)); err != nil {
2020-06-14 20:56:48 +02:00
if err == bcrypt.ErrMismatchedHashAndPassword {
return nil, errors.New("unauthorized")
} else {
2020-07-10 18:35:37 +02:00
return nil, errors.Wrap(err, "failed to compare token password hashes")
2020-06-14 20:56:48 +02:00
}
}
2020-06-14 17:58:50 +02:00
}
2020-11-27 16:02:10 +01:00
return &token, nil
2020-02-09 21:25:33 +01:00
}
func (r *queryResolver) ShareTokenValidatePassword(ctx context.Context, credentials models.ShareTokenCredentials) (bool, error) {
2020-11-27 16:02:10 +01:00
var token models.ShareToken
if err := r.DB(ctx).Where("value = ?", credentials.Token).First(&token).Error; err != nil {
2020-11-27 16:02:10 +01:00
if errors.Is(err, gorm.ErrRecordNotFound) {
return false, errors.New("share not found")
} else {
2020-07-10 18:35:37 +02:00
return false, errors.Wrap(err, "failed to get share token from database")
}
}
2020-06-14 20:56:48 +02:00
if token.Password == nil {
return true, nil
}
if credentials.Password == nil {
2020-06-14 20:56:48 +02:00
return false, nil
}
if err := bcrypt.CompareHashAndPassword([]byte(*token.Password), []byte(*credentials.Password)); err != nil {
2020-06-14 20:56:48 +02:00
if err == bcrypt.ErrMismatchedHashAndPassword {
return false, nil
} else {
2020-07-10 18:35:37 +02:00
return false, errors.Wrap(err, "could not compare token password hashes")
2020-06-14 20:56:48 +02:00
}
}
return true, nil
}
func (r *mutationResolver) ShareAlbum(ctx context.Context, albumID int, expire *time.Time, password *string) (*models.ShareToken, error) {
2020-02-09 21:25:33 +01:00
user := auth.UserFromContext(ctx)
if user == nil {
return nil, auth.ErrUnauthorized
}
return actions.AddAlbumShare(r.DB(ctx), user, albumID, expire, password)
2020-02-09 21:25:33 +01:00
}
func (r *mutationResolver) ShareMedia(ctx context.Context, mediaID int, expire *time.Time, password *string) (*models.ShareToken, error) {
2020-02-11 15:36:12 +01:00
user := auth.UserFromContext(ctx)
if user == nil {
return nil, auth.ErrUnauthorized
}
return actions.AddMediaShare(r.DB(ctx), user, mediaID, expire, password)
2020-02-11 15:36:12 +01:00
}
func (r *mutationResolver) DeleteShareToken(ctx context.Context, tokenValue string) (*models.ShareToken, error) {
user := auth.UserFromContext(ctx)
if user == nil {
return nil, auth.ErrUnauthorized
}
return actions.DeleteShareToken(r.DB(ctx), user.ID, tokenValue)
}
func (r *mutationResolver) ProtectShareToken(ctx context.Context, tokenValue string, password *string) (*models.ShareToken, error) {
user := auth.UserFromContext(ctx)
if user == nil {
return nil, auth.ErrUnauthorized
}
return actions.ProtectShareToken(r.DB(ctx), user.ID, tokenValue, password)
2020-02-09 21:25:33 +01:00
}