Replace database, mostly share token

This commit is contained in:
viktorstrate
2020-11-27 16:02:10 +01:00
parent 2b966aa672
commit 22e328b94b
4 changed files with 343 additions and 320 deletions

View File

@@ -40,10 +40,13 @@ type Config struct {
type ResolverRoot interface { type ResolverRoot interface {
Album() AlbumResolver Album() AlbumResolver
Media() MediaResolver Media() MediaResolver
MediaEXIF() MediaEXIFResolver
Mutation() MutationResolver Mutation() MutationResolver
Query() QueryResolver Query() QueryResolver
ShareToken() ShareTokenResolver ShareToken() ShareTokenResolver
Subscription() SubscriptionResolver Subscription() SubscriptionResolver
User() UserResolver
VideoMetadata() VideoMetadataResolver
} }
type DirectiveRoot struct { type DirectiveRoot struct {
@@ -213,26 +216,29 @@ type ComplexityRoot struct {
} }
type AlbumResolver interface { type AlbumResolver interface {
ID(ctx context.Context, obj *models.Album) (int, error)
Media(ctx context.Context, obj *models.Album, filter *models.Filter, onlyFavorites *bool) ([]*models.Media, error) Media(ctx context.Context, obj *models.Album, filter *models.Filter, onlyFavorites *bool) ([]*models.Media, error)
SubAlbums(ctx context.Context, obj *models.Album, filter *models.Filter) ([]*models.Album, error) SubAlbums(ctx context.Context, obj *models.Album, filter *models.Filter) ([]*models.Album, error)
ParentAlbum(ctx context.Context, obj *models.Album) (*models.Album, error)
Owner(ctx context.Context, obj *models.Album) (*models.User, error)
Thumbnail(ctx context.Context, obj *models.Album) (*models.Media, error) Thumbnail(ctx context.Context, obj *models.Album) (*models.Media, error)
Path(ctx context.Context, obj *models.Album) ([]*models.Album, error) Path(ctx context.Context, obj *models.Album) ([]*models.Album, error)
Shares(ctx context.Context, obj *models.Album) ([]*models.ShareToken, error) Shares(ctx context.Context, obj *models.Album) ([]*models.ShareToken, error)
} }
type MediaResolver interface { type MediaResolver interface {
ID(ctx context.Context, obj *models.Media) (int, error)
Thumbnail(ctx context.Context, obj *models.Media) (*models.MediaURL, error) Thumbnail(ctx context.Context, obj *models.Media) (*models.MediaURL, error)
HighRes(ctx context.Context, obj *models.Media) (*models.MediaURL, error) HighRes(ctx context.Context, obj *models.Media) (*models.MediaURL, error)
VideoWeb(ctx context.Context, obj *models.Media) (*models.MediaURL, error) VideoWeb(ctx context.Context, obj *models.Media) (*models.MediaURL, error)
Album(ctx context.Context, obj *models.Media) (*models.Album, error)
Exif(ctx context.Context, obj *models.Media) (*models.MediaEXIF, error)
VideoMetadata(ctx context.Context, obj *models.Media) (*models.VideoMetadata, error)
Shares(ctx context.Context, obj *models.Media) ([]*models.ShareToken, error) Shares(ctx context.Context, obj *models.Media) ([]*models.ShareToken, error)
Downloads(ctx context.Context, obj *models.Media) ([]*models.MediaDownload, error) Downloads(ctx context.Context, obj *models.Media) ([]*models.MediaDownload, error)
} }
type MediaEXIFResolver interface {
ID(ctx context.Context, obj *models.MediaEXIF) (int, error)
Media(ctx context.Context, obj *models.MediaEXIF) (*models.Media, error)
}
type MutationResolver interface { type MutationResolver interface {
AuthorizeUser(ctx context.Context, username string, password string) (*models.AuthorizeResult, error) AuthorizeUser(ctx context.Context, username string, password string) (*models.AuthorizeResult, error)
RegisterUser(ctx context.Context, username string, password string, rootPath string) (*models.AuthorizeResult, error) RegisterUser(ctx context.Context, username string, password string, rootPath string) (*models.AuthorizeResult, error)
@@ -266,15 +272,22 @@ type QueryResolver interface {
Search(ctx context.Context, query string, limitMedia *int, limitAlbums *int) (*models.SearchResult, error) Search(ctx context.Context, query string, limitMedia *int, limitAlbums *int) (*models.SearchResult, error)
} }
type ShareTokenResolver interface { type ShareTokenResolver interface {
Owner(ctx context.Context, obj *models.ShareToken) (*models.User, error) ID(ctx context.Context, obj *models.ShareToken) (int, error)
HasPassword(ctx context.Context, obj *models.ShareToken) (bool, error) HasPassword(ctx context.Context, obj *models.ShareToken) (bool, error)
Album(ctx context.Context, obj *models.ShareToken) (*models.Album, error)
Media(ctx context.Context, obj *models.ShareToken) (*models.Media, error)
} }
type SubscriptionResolver interface { type SubscriptionResolver interface {
Notification(ctx context.Context) (<-chan *models.Notification, error) Notification(ctx context.Context) (<-chan *models.Notification, error)
} }
type UserResolver interface {
ID(ctx context.Context, obj *models.User) (int, error)
}
type VideoMetadataResolver interface {
ID(ctx context.Context, obj *models.VideoMetadata) (int, error)
Media(ctx context.Context, obj *models.VideoMetadata) (*models.Media, error)
Bitrate(ctx context.Context, obj *models.VideoMetadata) (*int, error)
}
type executableSchema struct { type executableSchema struct {
resolvers ResolverRoot resolvers ResolverRoot
@@ -2261,13 +2274,13 @@ func (ec *executionContext) _Album_id(ctx context.Context, field graphql.Collect
Field: field, Field: field,
Args: nil, Args: nil,
IsMethod: true, IsMethod: true,
IsResolver: false, IsResolver: true,
} }
ctx = graphql.WithFieldContext(ctx, fc) ctx = graphql.WithFieldContext(ctx, fc)
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
ctx = rctx // use context from middleware stack in children ctx = rctx // use context from middleware stack in children
return obj.ID(), nil return ec.resolvers.Album().ID(rctx, obj)
}) })
if err != nil { if err != nil {
ec.Error(ctx, err) ec.Error(ctx, err)
@@ -2414,14 +2427,14 @@ func (ec *executionContext) _Album_parentAlbum(ctx context.Context, field graphq
Object: "Album", Object: "Album",
Field: field, Field: field,
Args: nil, Args: nil,
IsMethod: true, IsMethod: false,
IsResolver: true, IsResolver: false,
} }
ctx = graphql.WithFieldContext(ctx, fc) ctx = graphql.WithFieldContext(ctx, fc)
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
ctx = rctx // use context from middleware stack in children ctx = rctx // use context from middleware stack in children
return ec.resolvers.Album().ParentAlbum(rctx, obj) return obj.ParentAlbum, nil
}) })
if err != nil { if err != nil {
ec.Error(ctx, err) ec.Error(ctx, err)
@@ -2446,14 +2459,14 @@ func (ec *executionContext) _Album_owner(ctx context.Context, field graphql.Coll
Object: "Album", Object: "Album",
Field: field, Field: field,
Args: nil, Args: nil,
IsMethod: true, IsMethod: false,
IsResolver: true, IsResolver: false,
} }
ctx = graphql.WithFieldContext(ctx, fc) ctx = graphql.WithFieldContext(ctx, fc)
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
ctx = rctx // use context from middleware stack in children ctx = rctx // use context from middleware stack in children
return ec.resolvers.Album().Owner(rctx, obj) return obj.Owner, nil
}) })
if err != nil { if err != nil {
ec.Error(ctx, err) ec.Error(ctx, err)
@@ -2465,9 +2478,9 @@ func (ec *executionContext) _Album_owner(ctx context.Context, field graphql.Coll
} }
return graphql.Null return graphql.Null
} }
res := resTmp.(*models.User) res := resTmp.(models.User)
fc.Result = res fc.Result = res
return ec.marshalNUser2githubᚗcomᚋviktorstrateᚋphotoviewᚋapiᚋgraphqlᚋmodelsᚐUser(ctx, field.Selections, res) return ec.marshalNUser2githubᚗcomᚋviktorstrateᚋphotoviewᚋapiᚋgraphqlᚋmodelsᚐUser(ctx, field.Selections, res)
} }
func (ec *executionContext) _Album_filePath(ctx context.Context, field graphql.CollectedField, obj *models.Album) (ret graphql.Marshaler) { func (ec *executionContext) _Album_filePath(ctx context.Context, field graphql.CollectedField, obj *models.Album) (ret graphql.Marshaler) {
@@ -2718,13 +2731,13 @@ func (ec *executionContext) _Media_id(ctx context.Context, field graphql.Collect
Field: field, Field: field,
Args: nil, Args: nil,
IsMethod: true, IsMethod: true,
IsResolver: false, IsResolver: true,
} }
ctx = graphql.WithFieldContext(ctx, fc) ctx = graphql.WithFieldContext(ctx, fc)
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
ctx = rctx // use context from middleware stack in children ctx = rctx // use context from middleware stack in children
return obj.ID(), nil return ec.resolvers.Media().ID(rctx, obj)
}) })
if err != nil { if err != nil {
ec.Error(ctx, err) ec.Error(ctx, err)
@@ -2921,14 +2934,14 @@ func (ec *executionContext) _Media_album(ctx context.Context, field graphql.Coll
Object: "Media", Object: "Media",
Field: field, Field: field,
Args: nil, Args: nil,
IsMethod: true, IsMethod: false,
IsResolver: true, IsResolver: false,
} }
ctx = graphql.WithFieldContext(ctx, fc) ctx = graphql.WithFieldContext(ctx, fc)
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
ctx = rctx // use context from middleware stack in children ctx = rctx // use context from middleware stack in children
return ec.resolvers.Media().Album(rctx, obj) return obj.Album, nil
}) })
if err != nil { if err != nil {
ec.Error(ctx, err) ec.Error(ctx, err)
@@ -2940,9 +2953,9 @@ func (ec *executionContext) _Media_album(ctx context.Context, field graphql.Coll
} }
return graphql.Null return graphql.Null
} }
res := resTmp.(*models.Album) res := resTmp.(models.Album)
fc.Result = res fc.Result = res
return ec.marshalNAlbum2githubᚗcomᚋviktorstrateᚋphotoviewᚋapiᚋgraphqlᚋmodelsᚐAlbum(ctx, field.Selections, res) return ec.marshalNAlbum2githubᚗcomᚋviktorstrateᚋphotoviewᚋapiᚋgraphqlᚋmodelsᚐAlbum(ctx, field.Selections, res)
} }
func (ec *executionContext) _Media_exif(ctx context.Context, field graphql.CollectedField, obj *models.Media) (ret graphql.Marshaler) { func (ec *executionContext) _Media_exif(ctx context.Context, field graphql.CollectedField, obj *models.Media) (ret graphql.Marshaler) {
@@ -2956,14 +2969,14 @@ func (ec *executionContext) _Media_exif(ctx context.Context, field graphql.Colle
Object: "Media", Object: "Media",
Field: field, Field: field,
Args: nil, Args: nil,
IsMethod: true, IsMethod: false,
IsResolver: true, IsResolver: false,
} }
ctx = graphql.WithFieldContext(ctx, fc) ctx = graphql.WithFieldContext(ctx, fc)
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
ctx = rctx // use context from middleware stack in children ctx = rctx // use context from middleware stack in children
return ec.resolvers.Media().Exif(rctx, obj) return obj.Exif, nil
}) })
if err != nil { if err != nil {
ec.Error(ctx, err) ec.Error(ctx, err)
@@ -2972,9 +2985,9 @@ func (ec *executionContext) _Media_exif(ctx context.Context, field graphql.Colle
if resTmp == nil { if resTmp == nil {
return graphql.Null return graphql.Null
} }
res := resTmp.(*models.MediaEXIF) res := resTmp.(models.MediaEXIF)
fc.Result = res fc.Result = res
return ec.marshalOMediaEXIF2githubᚗcomᚋviktorstrateᚋphotoviewᚋapiᚋgraphqlᚋmodelsᚐMediaEXIF(ctx, field.Selections, res) return ec.marshalOMediaEXIF2githubᚗcomᚋviktorstrateᚋphotoviewᚋapiᚋgraphqlᚋmodelsᚐMediaEXIF(ctx, field.Selections, res)
} }
func (ec *executionContext) _Media_videoMetadata(ctx context.Context, field graphql.CollectedField, obj *models.Media) (ret graphql.Marshaler) { func (ec *executionContext) _Media_videoMetadata(ctx context.Context, field graphql.CollectedField, obj *models.Media) (ret graphql.Marshaler) {
@@ -2988,14 +3001,14 @@ func (ec *executionContext) _Media_videoMetadata(ctx context.Context, field grap
Object: "Media", Object: "Media",
Field: field, Field: field,
Args: nil, Args: nil,
IsMethod: true, IsMethod: false,
IsResolver: true, IsResolver: false,
} }
ctx = graphql.WithFieldContext(ctx, fc) ctx = graphql.WithFieldContext(ctx, fc)
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
ctx = rctx // use context from middleware stack in children ctx = rctx // use context from middleware stack in children
return ec.resolvers.Media().VideoMetadata(rctx, obj) return obj.VideoMetadata, nil
}) })
if err != nil { if err != nil {
ec.Error(ctx, err) ec.Error(ctx, err)
@@ -3231,13 +3244,13 @@ func (ec *executionContext) _MediaEXIF_id(ctx context.Context, field graphql.Col
Field: field, Field: field,
Args: nil, Args: nil,
IsMethod: true, IsMethod: true,
IsResolver: false, IsResolver: true,
} }
ctx = graphql.WithFieldContext(ctx, fc) ctx = graphql.WithFieldContext(ctx, fc)
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
ctx = rctx // use context from middleware stack in children ctx = rctx // use context from middleware stack in children
return obj.ID(), nil return ec.resolvers.MediaEXIF().ID(rctx, obj)
}) })
if err != nil { if err != nil {
ec.Error(ctx, err) ec.Error(ctx, err)
@@ -3266,13 +3279,13 @@ func (ec *executionContext) _MediaEXIF_media(ctx context.Context, field graphql.
Field: field, Field: field,
Args: nil, Args: nil,
IsMethod: true, IsMethod: true,
IsResolver: false, IsResolver: true,
} }
ctx = graphql.WithFieldContext(ctx, fc) ctx = graphql.WithFieldContext(ctx, fc)
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
ctx = rctx // use context from middleware stack in children ctx = rctx // use context from middleware stack in children
return obj.Media(), nil return ec.resolvers.MediaEXIF().Media(rctx, obj)
}) })
if err != nil { if err != nil {
ec.Error(ctx, err) ec.Error(ctx, err)
@@ -3744,9 +3757,9 @@ func (ec *executionContext) _MediaURL_fileSize(ctx context.Context, field graphq
} }
return graphql.Null return graphql.Null
} }
res := resTmp.(int) res := resTmp.(int64)
fc.Result = res fc.Result = res
return ec.marshalNInt2int(ctx, field.Selections, res) return ec.marshalNInt2int64(ctx, field.Selections, res)
} }
func (ec *executionContext) _Mutation_authorizeUser(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { func (ec *executionContext) _Mutation_authorizeUser(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) {
@@ -5556,13 +5569,13 @@ func (ec *executionContext) _ShareToken_id(ctx context.Context, field graphql.Co
Field: field, Field: field,
Args: nil, Args: nil,
IsMethod: true, IsMethod: true,
IsResolver: false, IsResolver: true,
} }
ctx = graphql.WithFieldContext(ctx, fc) ctx = graphql.WithFieldContext(ctx, fc)
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
ctx = rctx // use context from middleware stack in children ctx = rctx // use context from middleware stack in children
return obj.ID(), nil return ec.resolvers.ShareToken().ID(rctx, obj)
}) })
if err != nil { if err != nil {
ec.Error(ctx, err) ec.Error(ctx, err)
@@ -5625,14 +5638,14 @@ func (ec *executionContext) _ShareToken_owner(ctx context.Context, field graphql
Object: "ShareToken", Object: "ShareToken",
Field: field, Field: field,
Args: nil, Args: nil,
IsMethod: true, IsMethod: false,
IsResolver: true, IsResolver: false,
} }
ctx = graphql.WithFieldContext(ctx, fc) ctx = graphql.WithFieldContext(ctx, fc)
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
ctx = rctx // use context from middleware stack in children ctx = rctx // use context from middleware stack in children
return ec.resolvers.ShareToken().Owner(rctx, obj) return obj.Owner, nil
}) })
if err != nil { if err != nil {
ec.Error(ctx, err) ec.Error(ctx, err)
@@ -5644,9 +5657,9 @@ func (ec *executionContext) _ShareToken_owner(ctx context.Context, field graphql
} }
return graphql.Null return graphql.Null
} }
res := resTmp.(*models.User) res := resTmp.(models.User)
fc.Result = res fc.Result = res
return ec.marshalNUser2githubᚗcomᚋviktorstrateᚋphotoviewᚋapiᚋgraphqlᚋmodelsᚐUser(ctx, field.Selections, res) return ec.marshalNUser2githubᚗcomᚋviktorstrateᚋphotoviewᚋapiᚋgraphqlᚋmodelsᚐUser(ctx, field.Selections, res)
} }
func (ec *executionContext) _ShareToken_expire(ctx context.Context, field graphql.CollectedField, obj *models.ShareToken) (ret graphql.Marshaler) { func (ec *executionContext) _ShareToken_expire(ctx context.Context, field graphql.CollectedField, obj *models.ShareToken) (ret graphql.Marshaler) {
@@ -5727,14 +5740,14 @@ func (ec *executionContext) _ShareToken_album(ctx context.Context, field graphql
Object: "ShareToken", Object: "ShareToken",
Field: field, Field: field,
Args: nil, Args: nil,
IsMethod: true, IsMethod: false,
IsResolver: true, IsResolver: false,
} }
ctx = graphql.WithFieldContext(ctx, fc) ctx = graphql.WithFieldContext(ctx, fc)
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
ctx = rctx // use context from middleware stack in children ctx = rctx // use context from middleware stack in children
return ec.resolvers.ShareToken().Album(rctx, obj) return obj.Album, nil
}) })
if err != nil { if err != nil {
ec.Error(ctx, err) ec.Error(ctx, err)
@@ -5743,9 +5756,9 @@ func (ec *executionContext) _ShareToken_album(ctx context.Context, field graphql
if resTmp == nil { if resTmp == nil {
return graphql.Null return graphql.Null
} }
res := resTmp.(*models.Album) res := resTmp.(models.Album)
fc.Result = res fc.Result = res
return ec.marshalOAlbum2githubᚗcomᚋviktorstrateᚋphotoviewᚋapiᚋgraphqlᚋmodelsᚐAlbum(ctx, field.Selections, res) return ec.marshalOAlbum2githubᚗcomᚋviktorstrateᚋphotoviewᚋapiᚋgraphqlᚋmodelsᚐAlbum(ctx, field.Selections, res)
} }
func (ec *executionContext) _ShareToken_media(ctx context.Context, field graphql.CollectedField, obj *models.ShareToken) (ret graphql.Marshaler) { func (ec *executionContext) _ShareToken_media(ctx context.Context, field graphql.CollectedField, obj *models.ShareToken) (ret graphql.Marshaler) {
@@ -5759,14 +5772,14 @@ func (ec *executionContext) _ShareToken_media(ctx context.Context, field graphql
Object: "ShareToken", Object: "ShareToken",
Field: field, Field: field,
Args: nil, Args: nil,
IsMethod: true, IsMethod: false,
IsResolver: true, IsResolver: false,
} }
ctx = graphql.WithFieldContext(ctx, fc) ctx = graphql.WithFieldContext(ctx, fc)
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
ctx = rctx // use context from middleware stack in children ctx = rctx // use context from middleware stack in children
return ec.resolvers.ShareToken().Media(rctx, obj) return obj.Media, nil
}) })
if err != nil { if err != nil {
ec.Error(ctx, err) ec.Error(ctx, err)
@@ -5982,13 +5995,13 @@ func (ec *executionContext) _User_id(ctx context.Context, field graphql.Collecte
Field: field, Field: field,
Args: nil, Args: nil,
IsMethod: true, IsMethod: true,
IsResolver: false, IsResolver: true,
} }
ctx = graphql.WithFieldContext(ctx, fc) ctx = graphql.WithFieldContext(ctx, fc)
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
ctx = rctx // use context from middleware stack in children ctx = rctx // use context from middleware stack in children
return obj.ID(), nil return ec.resolvers.User().ID(rctx, obj)
}) })
if err != nil { if err != nil {
ec.Error(ctx, err) ec.Error(ctx, err)
@@ -6142,13 +6155,13 @@ func (ec *executionContext) _VideoMetadata_id(ctx context.Context, field graphql
Field: field, Field: field,
Args: nil, Args: nil,
IsMethod: true, IsMethod: true,
IsResolver: false, IsResolver: true,
} }
ctx = graphql.WithFieldContext(ctx, fc) ctx = graphql.WithFieldContext(ctx, fc)
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
ctx = rctx // use context from middleware stack in children ctx = rctx // use context from middleware stack in children
return obj.ID(), nil return ec.resolvers.VideoMetadata().ID(rctx, obj)
}) })
if err != nil { if err != nil {
ec.Error(ctx, err) ec.Error(ctx, err)
@@ -6177,13 +6190,13 @@ func (ec *executionContext) _VideoMetadata_media(ctx context.Context, field grap
Field: field, Field: field,
Args: nil, Args: nil,
IsMethod: true, IsMethod: true,
IsResolver: false, IsResolver: true,
} }
ctx = graphql.WithFieldContext(ctx, fc) ctx = graphql.WithFieldContext(ctx, fc)
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
ctx = rctx // use context from middleware stack in children ctx = rctx // use context from middleware stack in children
return obj.Media(), nil return ec.resolvers.VideoMetadata().Media(rctx, obj)
}) })
if err != nil { if err != nil {
ec.Error(ctx, err) ec.Error(ctx, err)
@@ -6380,14 +6393,14 @@ func (ec *executionContext) _VideoMetadata_bitrate(ctx context.Context, field gr
Object: "VideoMetadata", Object: "VideoMetadata",
Field: field, Field: field,
Args: nil, Args: nil,
IsMethod: false, IsMethod: true,
IsResolver: false, IsResolver: true,
} }
ctx = graphql.WithFieldContext(ctx, fc) ctx = graphql.WithFieldContext(ctx, fc)
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
ctx = rctx // use context from middleware stack in children ctx = rctx // use context from middleware stack in children
return obj.Bitrate, nil return ec.resolvers.VideoMetadata().Bitrate(rctx, obj)
}) })
if err != nil { if err != nil {
ec.Error(ctx, err) ec.Error(ctx, err)
@@ -7616,10 +7629,19 @@ func (ec *executionContext) _Album(ctx context.Context, sel ast.SelectionSet, ob
case "__typename": case "__typename":
out.Values[i] = graphql.MarshalString("Album") out.Values[i] = graphql.MarshalString("Album")
case "id": case "id":
out.Values[i] = ec._Album_id(ctx, field, obj) field := field
if out.Values[i] == graphql.Null { out.Concurrently(i, func() (res graphql.Marshaler) {
atomic.AddUint32(&invalids, 1) defer func() {
} if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
}
}()
res = ec._Album_id(ctx, field, obj)
if res == graphql.Null {
atomic.AddUint32(&invalids, 1)
}
return res
})
case "title": case "title":
out.Values[i] = ec._Album_title(ctx, field, obj) out.Values[i] = ec._Album_title(ctx, field, obj)
if out.Values[i] == graphql.Null { if out.Values[i] == graphql.Null {
@@ -7654,30 +7676,12 @@ func (ec *executionContext) _Album(ctx context.Context, sel ast.SelectionSet, ob
return res return res
}) })
case "parentAlbum": case "parentAlbum":
field := field out.Values[i] = ec._Album_parentAlbum(ctx, field, obj)
out.Concurrently(i, func() (res graphql.Marshaler) {
defer func() {
if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
}
}()
res = ec._Album_parentAlbum(ctx, field, obj)
return res
})
case "owner": case "owner":
field := field out.Values[i] = ec._Album_owner(ctx, field, obj)
out.Concurrently(i, func() (res graphql.Marshaler) { if out.Values[i] == graphql.Null {
defer func() { atomic.AddUint32(&invalids, 1)
if r := recover(); r != nil { }
ec.Error(ctx, ec.Recover(ctx, r))
}
}()
res = ec._Album_owner(ctx, field, obj)
if res == graphql.Null {
atomic.AddUint32(&invalids, 1)
}
return res
})
case "filePath": case "filePath":
out.Values[i] = ec._Album_filePath(ctx, field, obj) out.Values[i] = ec._Album_filePath(ctx, field, obj)
if out.Values[i] == graphql.Null { if out.Values[i] == graphql.Null {
@@ -7776,10 +7780,19 @@ func (ec *executionContext) _Media(ctx context.Context, sel ast.SelectionSet, ob
case "__typename": case "__typename":
out.Values[i] = graphql.MarshalString("Media") out.Values[i] = graphql.MarshalString("Media")
case "id": case "id":
out.Values[i] = ec._Media_id(ctx, field, obj) field := field
if out.Values[i] == graphql.Null { out.Concurrently(i, func() (res graphql.Marshaler) {
atomic.AddUint32(&invalids, 1) defer func() {
} if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
}
}()
res = ec._Media_id(ctx, field, obj)
if res == graphql.Null {
atomic.AddUint32(&invalids, 1)
}
return res
})
case "title": case "title":
out.Values[i] = ec._Media_title(ctx, field, obj) out.Values[i] = ec._Media_title(ctx, field, obj)
if out.Values[i] == graphql.Null { if out.Values[i] == graphql.Null {
@@ -7827,41 +7840,14 @@ func (ec *executionContext) _Media(ctx context.Context, sel ast.SelectionSet, ob
return res return res
}) })
case "album": case "album":
field := field out.Values[i] = ec._Media_album(ctx, field, obj)
out.Concurrently(i, func() (res graphql.Marshaler) { if out.Values[i] == graphql.Null {
defer func() { atomic.AddUint32(&invalids, 1)
if r := recover(); r != nil { }
ec.Error(ctx, ec.Recover(ctx, r))
}
}()
res = ec._Media_album(ctx, field, obj)
if res == graphql.Null {
atomic.AddUint32(&invalids, 1)
}
return res
})
case "exif": case "exif":
field := field out.Values[i] = ec._Media_exif(ctx, field, obj)
out.Concurrently(i, func() (res graphql.Marshaler) {
defer func() {
if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
}
}()
res = ec._Media_exif(ctx, field, obj)
return res
})
case "videoMetadata": case "videoMetadata":
field := field out.Values[i] = ec._Media_videoMetadata(ctx, field, obj)
out.Concurrently(i, func() (res graphql.Marshaler) {
defer func() {
if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
}
}()
res = ec._Media_videoMetadata(ctx, field, obj)
return res
})
case "favorite": case "favorite":
out.Values[i] = ec._Media_favorite(ctx, field, obj) out.Values[i] = ec._Media_favorite(ctx, field, obj)
if out.Values[i] == graphql.Null { if out.Values[i] == graphql.Null {
@@ -7955,15 +7941,33 @@ func (ec *executionContext) _MediaEXIF(ctx context.Context, sel ast.SelectionSet
case "__typename": case "__typename":
out.Values[i] = graphql.MarshalString("MediaEXIF") out.Values[i] = graphql.MarshalString("MediaEXIF")
case "id": case "id":
out.Values[i] = ec._MediaEXIF_id(ctx, field, obj) field := field
if out.Values[i] == graphql.Null { out.Concurrently(i, func() (res graphql.Marshaler) {
invalids++ defer func() {
} if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
}
}()
res = ec._MediaEXIF_id(ctx, field, obj)
if res == graphql.Null {
atomic.AddUint32(&invalids, 1)
}
return res
})
case "media": case "media":
out.Values[i] = ec._MediaEXIF_media(ctx, field, obj) field := field
if out.Values[i] == graphql.Null { out.Concurrently(i, func() (res graphql.Marshaler) {
invalids++ defer func() {
} if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
}
}()
res = ec._MediaEXIF_media(ctx, field, obj)
if res == graphql.Null {
atomic.AddUint32(&invalids, 1)
}
return res
})
case "camera": case "camera":
out.Values[i] = ec._MediaEXIF_camera(ctx, field, obj) out.Values[i] = ec._MediaEXIF_camera(ctx, field, obj)
case "maker": case "maker":
@@ -8461,16 +8465,6 @@ func (ec *executionContext) _ShareToken(ctx context.Context, sel ast.SelectionSe
case "__typename": case "__typename":
out.Values[i] = graphql.MarshalString("ShareToken") out.Values[i] = graphql.MarshalString("ShareToken")
case "id": case "id":
out.Values[i] = ec._ShareToken_id(ctx, field, obj)
if out.Values[i] == graphql.Null {
atomic.AddUint32(&invalids, 1)
}
case "token":
out.Values[i] = ec._ShareToken_token(ctx, field, obj)
if out.Values[i] == graphql.Null {
atomic.AddUint32(&invalids, 1)
}
case "owner":
field := field field := field
out.Concurrently(i, func() (res graphql.Marshaler) { out.Concurrently(i, func() (res graphql.Marshaler) {
defer func() { defer func() {
@@ -8478,12 +8472,22 @@ func (ec *executionContext) _ShareToken(ctx context.Context, sel ast.SelectionSe
ec.Error(ctx, ec.Recover(ctx, r)) ec.Error(ctx, ec.Recover(ctx, r))
} }
}() }()
res = ec._ShareToken_owner(ctx, field, obj) res = ec._ShareToken_id(ctx, field, obj)
if res == graphql.Null { if res == graphql.Null {
atomic.AddUint32(&invalids, 1) atomic.AddUint32(&invalids, 1)
} }
return res return res
}) })
case "token":
out.Values[i] = ec._ShareToken_token(ctx, field, obj)
if out.Values[i] == graphql.Null {
atomic.AddUint32(&invalids, 1)
}
case "owner":
out.Values[i] = ec._ShareToken_owner(ctx, field, obj)
if out.Values[i] == graphql.Null {
atomic.AddUint32(&invalids, 1)
}
case "expire": case "expire":
out.Values[i] = ec._ShareToken_expire(ctx, field, obj) out.Values[i] = ec._ShareToken_expire(ctx, field, obj)
case "hasPassword": case "hasPassword":
@@ -8501,27 +8505,9 @@ func (ec *executionContext) _ShareToken(ctx context.Context, sel ast.SelectionSe
return res return res
}) })
case "album": case "album":
field := field out.Values[i] = ec._ShareToken_album(ctx, field, obj)
out.Concurrently(i, func() (res graphql.Marshaler) {
defer func() {
if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
}
}()
res = ec._ShareToken_album(ctx, field, obj)
return res
})
case "media": case "media":
field := field out.Values[i] = ec._ShareToken_media(ctx, field, obj)
out.Concurrently(i, func() (res graphql.Marshaler) {
defer func() {
if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
}
}()
res = ec._ShareToken_media(ctx, field, obj)
return res
})
default: default:
panic("unknown field " + strconv.Quote(field.Name)) panic("unknown field " + strconv.Quote(field.Name))
} }
@@ -8602,24 +8588,33 @@ func (ec *executionContext) _User(ctx context.Context, sel ast.SelectionSet, obj
case "__typename": case "__typename":
out.Values[i] = graphql.MarshalString("User") out.Values[i] = graphql.MarshalString("User")
case "id": case "id":
out.Values[i] = ec._User_id(ctx, field, obj) field := field
if out.Values[i] == graphql.Null { out.Concurrently(i, func() (res graphql.Marshaler) {
invalids++ defer func() {
} if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
}
}()
res = ec._User_id(ctx, field, obj)
if res == graphql.Null {
atomic.AddUint32(&invalids, 1)
}
return res
})
case "username": case "username":
out.Values[i] = ec._User_username(ctx, field, obj) out.Values[i] = ec._User_username(ctx, field, obj)
if out.Values[i] == graphql.Null { if out.Values[i] == graphql.Null {
invalids++ atomic.AddUint32(&invalids, 1)
} }
case "rootPath": case "rootPath":
out.Values[i] = ec._User_rootPath(ctx, field, obj) out.Values[i] = ec._User_rootPath(ctx, field, obj)
if out.Values[i] == graphql.Null { if out.Values[i] == graphql.Null {
invalids++ atomic.AddUint32(&invalids, 1)
} }
case "admin": case "admin":
out.Values[i] = ec._User_admin(ctx, field, obj) out.Values[i] = ec._User_admin(ctx, field, obj)
if out.Values[i] == graphql.Null { if out.Values[i] == graphql.Null {
invalids++ atomic.AddUint32(&invalids, 1)
} }
default: default:
panic("unknown field " + strconv.Quote(field.Name)) panic("unknown field " + strconv.Quote(field.Name))
@@ -8644,36 +8639,63 @@ func (ec *executionContext) _VideoMetadata(ctx context.Context, sel ast.Selectio
case "__typename": case "__typename":
out.Values[i] = graphql.MarshalString("VideoMetadata") out.Values[i] = graphql.MarshalString("VideoMetadata")
case "id": case "id":
out.Values[i] = ec._VideoMetadata_id(ctx, field, obj) field := field
if out.Values[i] == graphql.Null { out.Concurrently(i, func() (res graphql.Marshaler) {
invalids++ defer func() {
} if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
}
}()
res = ec._VideoMetadata_id(ctx, field, obj)
if res == graphql.Null {
atomic.AddUint32(&invalids, 1)
}
return res
})
case "media": case "media":
out.Values[i] = ec._VideoMetadata_media(ctx, field, obj) field := field
if out.Values[i] == graphql.Null { out.Concurrently(i, func() (res graphql.Marshaler) {
invalids++ defer func() {
} if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
}
}()
res = ec._VideoMetadata_media(ctx, field, obj)
if res == graphql.Null {
atomic.AddUint32(&invalids, 1)
}
return res
})
case "width": case "width":
out.Values[i] = ec._VideoMetadata_width(ctx, field, obj) out.Values[i] = ec._VideoMetadata_width(ctx, field, obj)
if out.Values[i] == graphql.Null { if out.Values[i] == graphql.Null {
invalids++ atomic.AddUint32(&invalids, 1)
} }
case "height": case "height":
out.Values[i] = ec._VideoMetadata_height(ctx, field, obj) out.Values[i] = ec._VideoMetadata_height(ctx, field, obj)
if out.Values[i] == graphql.Null { if out.Values[i] == graphql.Null {
invalids++ atomic.AddUint32(&invalids, 1)
} }
case "duration": case "duration":
out.Values[i] = ec._VideoMetadata_duration(ctx, field, obj) out.Values[i] = ec._VideoMetadata_duration(ctx, field, obj)
if out.Values[i] == graphql.Null { if out.Values[i] == graphql.Null {
invalids++ atomic.AddUint32(&invalids, 1)
} }
case "codec": case "codec":
out.Values[i] = ec._VideoMetadata_codec(ctx, field, obj) out.Values[i] = ec._VideoMetadata_codec(ctx, field, obj)
case "framerate": case "framerate":
out.Values[i] = ec._VideoMetadata_framerate(ctx, field, obj) out.Values[i] = ec._VideoMetadata_framerate(ctx, field, obj)
case "bitrate": case "bitrate":
out.Values[i] = ec._VideoMetadata_bitrate(ctx, field, obj) field := field
out.Concurrently(i, func() (res graphql.Marshaler) {
defer func() {
if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
}
}()
res = ec._VideoMetadata_bitrate(ctx, field, obj)
return res
})
case "colorProfile": case "colorProfile":
out.Values[i] = ec._VideoMetadata_colorProfile(ctx, field, obj) out.Values[i] = ec._VideoMetadata_colorProfile(ctx, field, obj)
case "audio": case "audio":
@@ -9065,6 +9087,21 @@ func (ec *executionContext) marshalNInt2int(ctx context.Context, sel ast.Selecti
return res return res
} }
func (ec *executionContext) unmarshalNInt2int64(ctx context.Context, v interface{}) (int64, error) {
res, err := graphql.UnmarshalInt64(v)
return res, graphql.ErrorOnPath(ctx, err)
}
func (ec *executionContext) marshalNInt2int64(ctx context.Context, sel ast.SelectionSet, v int64) graphql.Marshaler {
res := graphql.MarshalInt64(v)
if res == graphql.Null {
if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) {
ec.Errorf(ctx, "must not be null")
}
}
return res
}
func (ec *executionContext) unmarshalNInt2ᚕintᚄ(ctx context.Context, v interface{}) ([]int, error) { func (ec *executionContext) unmarshalNInt2ᚕintᚄ(ctx context.Context, v interface{}) ([]int, error) {
var vSlice []interface{} var vSlice []interface{}
if v != nil { if v != nil {
@@ -9629,6 +9666,10 @@ func (ec *executionContext) marshalN__TypeKind2string(ctx context.Context, sel a
return res return res
} }
func (ec *executionContext) marshalOAlbum2githubᚗcomᚋviktorstrateᚋphotoviewᚋapiᚋgraphqlᚋmodelsᚐAlbum(ctx context.Context, sel ast.SelectionSet, v models.Album) graphql.Marshaler {
return ec._Album(ctx, sel, &v)
}
func (ec *executionContext) marshalOAlbum2ᚖgithubᚗcomᚋviktorstrateᚋphotoviewᚋapiᚋgraphqlᚋmodelsᚐAlbum(ctx context.Context, sel ast.SelectionSet, v *models.Album) graphql.Marshaler { func (ec *executionContext) marshalOAlbum2ᚖgithubᚗcomᚋviktorstrateᚋphotoviewᚋapiᚋgraphqlᚋmodelsᚐAlbum(ctx context.Context, sel ast.SelectionSet, v *models.Album) graphql.Marshaler {
if v == nil { if v == nil {
return graphql.Null return graphql.Null
@@ -9712,11 +9753,8 @@ func (ec *executionContext) marshalOMedia2ᚖgithubᚗcomᚋviktorstrateᚋphoto
return ec._Media(ctx, sel, v) return ec._Media(ctx, sel, v)
} }
func (ec *executionContext) marshalOMediaEXIF2githubᚗcomᚋviktorstrateᚋphotoviewᚋapiᚋgraphqlᚋmodelsᚐMediaEXIF(ctx context.Context, sel ast.SelectionSet, v *models.MediaEXIF) graphql.Marshaler { func (ec *executionContext) marshalOMediaEXIF2githubᚗcomᚋviktorstrateᚋphotoviewᚋapiᚋgraphqlᚋmodelsᚐMediaEXIF(ctx context.Context, sel ast.SelectionSet, v models.MediaEXIF) graphql.Marshaler {
if v == nil { return ec._MediaEXIF(ctx, sel, &v)
return graphql.Null
}
return ec._MediaEXIF(ctx, sel, v)
} }
func (ec *executionContext) marshalOMediaURL2ᚖgithubᚗcomᚋviktorstrateᚋphotoviewᚋapiᚋgraphqlᚋmodelsᚐMediaURL(ctx context.Context, sel ast.SelectionSet, v *models.MediaURL) graphql.Marshaler { func (ec *executionContext) marshalOMediaURL2ᚖgithubᚗcomᚋviktorstrateᚋphotoviewᚋapiᚋgraphqlᚋmodelsᚐMediaURL(ctx context.Context, sel ast.SelectionSet, v *models.MediaURL) graphql.Marshaler {

View File

@@ -52,13 +52,13 @@ type SearchResult struct {
} }
// General information about the site // General information about the site
// type SiteInfo struct { type SiteInfo struct {
// InitialSetup bool `json:"initialSetup"` InitialSetup bool `json:"initialSetup"`
// // How often automatic scans should be initiated in seconds // How often automatic scans should be initiated in seconds
// PeriodicScanInterval int `json:"periodicScanInterval"` PeriodicScanInterval int `json:"periodicScanInterval"`
// // How many max concurrent scanner jobs that should run at once // How many max concurrent scanner jobs that should run at once
// ConcurrentWorkers int `json:"concurrentWorkers"` ConcurrentWorkers int `json:"concurrentWorkers"`
// } }
type MediaType string type MediaType string

View File

@@ -25,13 +25,14 @@ func (r *mutationResolver) ScanAll(ctx context.Context) (*models.ScannerResult,
} }
func (r *mutationResolver) ScanUser(ctx context.Context, userID int) (*models.ScannerResult, error) { func (r *mutationResolver) ScanUser(ctx context.Context, userID int) (*models.ScannerResult, error) {
row := r.Database.QueryRow("SELECT * FROM user WHERE user_id = ?", userID)
user, err := models.NewUserFromRow(row) var user models.User
if err != nil {
if err := r.Database.First(&user, userID).Error; err != nil {
return nil, errors.Wrap(err, "get user from database") return nil, errors.Wrap(err, "get user from database")
} }
scanner.AddUserToQueue(user) scanner.AddUserToQueue(&user)
startMessage := "Scanner started" startMessage := "Scanner started"
return &models.ScannerResult{ return &models.ScannerResult{
@@ -46,21 +47,18 @@ func (r *mutationResolver) SetPeriodicScanInterval(ctx context.Context, interval
return 0, errors.New("interval must be 0 or above") return 0, errors.New("interval must be 0 or above")
} }
_, err := r.Database.Exec("UPDATE site_info SET periodic_scan_interval = ?", interval) if err := r.Database.Model(&models.SiteInfo{}).Update("periodic_scan_interval", interval).Error; err != nil {
if err != nil {
return 0, err return 0, err
} }
var dbInterval int var siteInfo models.SiteInfo
if err := r.Database.First(&siteInfo).Error; err != nil {
row := r.Database.QueryRow("SELECT periodic_scan_interval FROM site_info")
if err = row.Scan(&dbInterval); err != nil {
return 0, err return 0, err
} }
scanner.ChangePeriodicScanInterval(time.Duration(dbInterval) * time.Second) scanner.ChangePeriodicScanInterval(time.Duration(siteInfo.PeriodicScanInterval) * time.Second)
return dbInterval, nil return siteInfo.PeriodicScanInterval, nil
} }
func (r *mutationResolver) SetScannerConcurrentWorkers(ctx context.Context, workers int) (int, error) { func (r *mutationResolver) SetScannerConcurrentWorkers(ctx context.Context, workers int) (int, error) {
@@ -68,19 +66,16 @@ func (r *mutationResolver) SetScannerConcurrentWorkers(ctx context.Context, work
return 0, errors.New("concurrent workers must at least be 1") return 0, errors.New("concurrent workers must at least be 1")
} }
_, err := r.Database.Exec("UPDATE site_info SET concurrent_workers = ?", workers) if err := r.Database.Model(&models.SiteInfo{}).Update("concurrent_workers", workers).Error; err != nil {
if err != nil {
return 0, err return 0, err
} }
var dbWorkers int var siteInfo models.SiteInfo
if err := r.Database.First(&siteInfo).Error; err != nil {
row := r.Database.QueryRow("SELECT concurrent_workers FROM site_info")
if err = row.Scan(&dbWorkers); err != nil {
return 0, err return 0, err
} }
scanner.ChangeScannerConcurrentWorkers(dbWorkers) scanner.ChangeScannerConcurrentWorkers(siteInfo.ConcurrentWorkers)
return dbWorkers, nil return siteInfo.ConcurrentWorkers, nil
} }

View File

@@ -2,7 +2,6 @@ package resolvers
import ( import (
"context" "context"
"database/sql"
"time" "time"
"github.com/pkg/errors" "github.com/pkg/errors"
@@ -23,38 +22,36 @@ func (r *Resolver) ShareToken() api.ShareTokenResolver {
return &shareTokenResolver{r} return &shareTokenResolver{r}
} }
func (r *shareTokenResolver) Owner(ctx context.Context, obj *models.ShareToken) (*models.User, error) { // PROBABLY NOT NEEDED ANYMORE
row := r.Database.QueryRow("SELECT * FROM user WHERE user.user_id = ?", obj.OwnerID)
return models.NewUserFromRow(row)
}
func (r *shareTokenResolver) Album(ctx context.Context, obj *models.ShareToken) (*models.Album, error) { // func (r *shareTokenResolver) Owner(ctx context.Context, obj *models.ShareToken) (*models.User, error) {
row := r.Database.QueryRow("SELECT * FROM album WHERE album.album_id = ?", obj.AlbumID) // var user models.User
album, err := models.NewAlbumFromRow(row) // if err := r.Database.First(&user, obj.OwnerID).Error; err != nil {
if err != nil { // return nil, err
if err == sql.ErrNoRows { // }
return nil, nil
} else {
return nil, errors.Wrap(err, "could not get album of share token from database")
}
}
return album, nil // return &user, nil
} // }
func (r *shareTokenResolver) Media(ctx context.Context, obj *models.ShareToken) (*models.Media, error) { // func (r *shareTokenResolver) Album(ctx context.Context, obj *models.ShareToken) (*models.Album, error) {
row := r.Database.QueryRow("SELECT * FROM media WHERE media.media_id = ?", obj.MediaID)
media, err := models.NewMediaFromRow(row)
if err != nil {
if err == sql.ErrNoRows {
return nil, nil
} else {
return nil, errors.Wrap(err, "could not get media of share token from database")
}
}
return media, nil // var album models.Album
} // if err := r.Database.First(&album, obj.AlbumID).Error; err != nil {
// return nil, err
// }
// return &album, nil
// }
// func (r *shareTokenResolver) Media(ctx context.Context, obj *models.ShareToken) (*models.Media, error) {
// var media models.Media
// if err := r.Database.First(&media, obj.MediaID).Error; err != nil {
// return nil, err
// }
// return &media, nil
// }
func (r *shareTokenResolver) HasPassword(ctx context.Context, obj *models.ShareToken) (bool, error) { func (r *shareTokenResolver) HasPassword(ctx context.Context, obj *models.ShareToken) (bool, error) {
hasPassword := obj.Password != nil hasPassword := obj.Password != nil
@@ -63,10 +60,9 @@ func (r *shareTokenResolver) HasPassword(ctx context.Context, obj *models.ShareT
func (r *queryResolver) ShareToken(ctx context.Context, tokenValue string, password *string) (*models.ShareToken, error) { func (r *queryResolver) ShareToken(ctx context.Context, tokenValue string, password *string) (*models.ShareToken, error) {
row := r.Database.QueryRow("SELECT * FROM share_token WHERE value = ?", tokenValue) var token models.ShareToken
token, err := models.NewShareTokenFromRow(row) if err := r.Database.Where("value = ?", tokenValue).First(&token).Error; err != nil {
if err != nil { if errors.Is(err, gorm.ErrRecordNotFound) {
if err == sql.ErrNoRows {
return nil, errors.New("share not found") return nil, errors.New("share not found")
} else { } else {
return nil, errors.Wrap(err, "failed to get share token from database") return nil, errors.Wrap(err, "failed to get share token from database")
@@ -83,14 +79,13 @@ func (r *queryResolver) ShareToken(ctx context.Context, tokenValue string, passw
} }
} }
return token, nil return &token, nil
} }
func (r *queryResolver) ShareTokenValidatePassword(ctx context.Context, tokenValue string, password *string) (bool, error) { func (r *queryResolver) ShareTokenValidatePassword(ctx context.Context, tokenValue string, password *string) (bool, error) {
row := r.Database.QueryRow("SELECT * FROM share_token WHERE value = ?", tokenValue) var token models.ShareToken
token, err := models.NewShareTokenFromRow(row) if err := r.Database.Where("value = ?", tokenValue).First(&token).Error; err != nil {
if err != nil { if errors.Is(err, gorm.ErrRecordNotFound) {
if err == sql.ErrNoRows {
return false, errors.New("share not found") return false, errors.New("share not found")
} else { } else {
return false, errors.Wrap(err, "failed to get share token from database") return false, errors.Wrap(err, "failed to get share token from database")
@@ -116,93 +111,92 @@ func (r *queryResolver) ShareTokenValidatePassword(ctx context.Context, tokenVal
return true, nil return true, nil
} }
func (r *mutationResolver) ShareAlbum(ctx context.Context, albumID int, expire *time.Time, password *string) (*models.ShareToken, error) { func (r *mutationResolver) ShareAlbum(ctx context.Context, albumID uint, expire *time.Time, password *string) (*models.ShareToken, error) {
user := auth.UserFromContext(ctx) user := auth.UserFromContext(ctx)
if user == nil { if user == nil {
return nil, auth.ErrUnauthorized return nil, auth.ErrUnauthorized
} }
rows, err := r.Database.Query("SELECT owner_id FROM album WHERE album.album_id = ? AND album.owner_id = ?", albumID, user.UserID) var count int64
if err != nil { if err := r.Database.Model(&models.Album{}).Where("owner_id = ?", user.ID).Count(&count).Error; err != nil {
return nil, errors.Wrap(err, "failed to validate album owner with database") return nil, errors.Wrap(err, "failed to validate album owner with database")
} }
if rows.Next() == false {
if count == 0 {
return nil, auth.ErrUnauthorized return nil, auth.ErrUnauthorized
} }
rows.Close()
var hashed_password *string = nil var hashedPassword *string = nil
if password != nil { if password != nil {
hashedPassBytes, err := bcrypt.GenerateFromPassword([]byte(*password), 12) hashedPassBytes, err := bcrypt.GenerateFromPassword([]byte(*password), 12)
if err != nil { if err != nil {
return nil, errors.Wrap(err, "failed to hash token password") return nil, errors.Wrap(err, "failed to hash token password")
} }
hashed_str := string(hashedPassBytes) hashedStr := string(hashedPassBytes)
hashed_password = &hashed_str hashedPassword = &hashedStr
} }
token := utils.GenerateToken() shareToken := models.ShareToken{
res, err := r.Database.Exec("INSERT INTO share_token (value, owner_id, expire, password, album_id) VALUES (?, ?, ?, ?, ?)", token, user.UserID, expire, hashed_password, albumID) Value: utils.GenerateToken(),
if err != nil { OwnerID: user.ID,
Expire: expire,
Password: hashedPassword,
AlbumID: &albumID,
MediaID: nil,
}
if err := r.Database.Create(&shareToken).Error; err != nil {
return nil, errors.Wrap(err, "failed to insert new share token into database") return nil, errors.Wrap(err, "failed to insert new share token into database")
} }
token_id, err := res.LastInsertId() return &shareToken, nil
if err != nil {
return nil, errors.Wrap(err, "could not get database id of new album share token")
}
return &models.ShareToken{
TokenID: int(token_id),
Value: token,
OwnerID: user.UserID,
Expire: expire,
Password: password,
AlbumID: &albumID,
MediaID: nil,
}, nil
} }
func (r *mutationResolver) ShareMedia(ctx context.Context, mediaID int, expire *time.Time, password *string) (*models.ShareToken, error) { func (r *mutationResolver) ShareMedia(ctx context.Context, mediaID uint, expire *time.Time, password *string) (*models.ShareToken, error) {
user := auth.UserFromContext(ctx) user := auth.UserFromContext(ctx)
if user == nil { if user == nil {
return nil, auth.ErrUnauthorized return nil, auth.ErrUnauthorized
} }
rows, err := r.Database.Query("SELECT owner_id FROM album, media WHERE media.media_id = ? AND media.album_id = album.album_id AND album.owner_id = ?", mediaID, user.UserID) var media models.Media
if err := r.Database.Where("owner_id = ?", user.ID).First(&media, mediaID).Error; err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return nil, auth.ErrUnauthorized
} else {
return nil, errors.Wrap(err, "failed to validate media owner with database")
}
}
var count int64
err := r.Database.Raw("SELECT owner_id FROM album, media WHERE media.media_id = ? AND media.album_id = album.album_id AND album.owner_id = ?", mediaID, user.ID).Count(&count).Error
if err != nil { if err != nil {
return nil, errors.Wrap(err, "error validating owner of media with database") return nil, errors.Wrap(err, "error validating owner of media with database")
} }
if rows.Next() == false {
if count == 0 {
return nil, auth.ErrUnauthorized return nil, auth.ErrUnauthorized
} }
rows.Close()
hashed_password, err := hashSharePassword(password) hashedPassword, err := hashSharePassword(password)
if err != nil { if err != nil {
return nil, err return nil, err
} }
token := utils.GenerateToken() shareToken := models.ShareToken{
res, err := r.Database.Exec("INSERT INTO share_token (value, owner_id, expire, password, media_id) VALUES (?, ?, ?, ?, ?)", token, user.UserID, expire, hashed_password, mediaID) Value: utils.GenerateToken(),
if err != nil { OwnerID: user.ID,
Expire: expire,
Password: hashedPassword,
AlbumID: nil,
MediaID: &mediaID,
}
if err := r.Database.Create(&shareToken).Error; err != nil {
return nil, errors.Wrap(err, "failed to insert new share token into database") return nil, errors.Wrap(err, "failed to insert new share token into database")
} }
token_id, err := res.LastInsertId() return &shareToken, nil
if err != nil {
return nil, errors.Wrap(err, "could not get database id of new media share token")
}
return &models.ShareToken{
TokenID: int(token_id),
Value: token,
OwnerID: user.UserID,
Expire: expire,
Password: password,
AlbumID: nil,
MediaID: &mediaID,
}, nil
} }
func (r *mutationResolver) DeleteShareToken(ctx context.Context, tokenValue string) (*models.ShareToken, error) { func (r *mutationResolver) DeleteShareToken(ctx context.Context, tokenValue string) (*models.ShareToken, error) {
@@ -216,7 +210,7 @@ func (r *mutationResolver) DeleteShareToken(ctx context.Context, tokenValue stri
return nil, err return nil, err
} }
if _, err := r.Database.Exec("DELETE FROM share_token WHERE token_id = ?", token.TokenID); err != nil { if err := r.Database.Delete(&token).Error; err != nil {
return nil, errors.Wrapf(err, "failed to delete share token (%s) from database", tokenValue) return nil, errors.Wrapf(err, "failed to delete share token (%s) from database", tokenValue)
} }
@@ -234,46 +228,42 @@ func (r *mutationResolver) ProtectShareToken(ctx context.Context, tokenValue str
return nil, err return nil, err
} }
hashed_password, err := hashSharePassword(password) hashedPassword, err := hashSharePassword(password)
if err != nil { if err != nil {
return nil, err return nil, err
} }
_, err = r.Database.Exec("UPDATE share_token SET password = ? WHERE token_id = ?", hashed_password, token.TokenID) token.Password = hashedPassword
if err != nil {
if err := r.Database.Save(&token).Error; err != nil {
return nil, errors.Wrap(err, "failed to update password for share token") return nil, errors.Wrap(err, "failed to update password for share token")
} }
updatedToken := r.Database.QueryRow("SELECT * FROM share_token WHERE value = ?", tokenValue) return token, nil
return models.NewShareTokenFromRow(updatedToken)
} }
func hashSharePassword(password *string) (*string, error) { func hashSharePassword(password *string) (*string, error) {
var hashed_password *string = nil var hashedPassword *string = nil
if password != nil { if password != nil {
hashedPassBytes, err := bcrypt.GenerateFromPassword([]byte(*password), 12) hashedPassBytes, err := bcrypt.GenerateFromPassword([]byte(*password), 12)
if err != nil { if err != nil {
return nil, errors.Wrap(err, "failed to generate hash for share password") return nil, errors.Wrap(err, "failed to generate hash for share password")
} }
hashed_str := string(hashedPassBytes) hashedStr := string(hashedPassBytes)
hashed_password = &hashed_str hashedPassword = &hashedStr
} }
return hashed_password, nil return hashedPassword, nil
} }
func getUserToken(db *gorm.DB, user *models.User, tokenValue string) (*models.ShareToken, error) { func getUserToken(db *gorm.DB, user *models.User, tokenValue string) (*models.ShareToken, error) {
row := db.QueryRow(`
SELECT share_token.* FROM share_token, user WHERE
share_token.value = ? AND
share_token.owner_id = user.user_id AND
(user.user_id = ? OR user.admin = TRUE)
`, tokenValue, user.UserID)
token, err := models.NewShareTokenFromRow(row) var token models.ShareToken
err := db.Where("share_tokens.value = ?", tokenValue).Joins("Owner").Where("users.id = ? OR users.admin = TRUE").First(&token).Error
if err != nil { if err != nil {
return nil, errors.Wrap(err, "failed to get user share token from database") return nil, errors.Wrap(err, "failed to get user share token from database")
} }
return token, nil return &token, nil
} }