1
Fork 0

Further work on shares

This commit is contained in:
viktorstrate 2020-02-11 15:36:12 +01:00
parent 687b4f4f7f
commit 0f7f703982
6 changed files with 154 additions and 15 deletions

View File

@ -69,6 +69,7 @@ type ComplexityRoot struct {
Mutation struct {
AuthorizeUser func(childComplexity int, username string, password string) int
DeleteShareToken func(childComplexity int, token string) int
InitialSetupWizard func(childComplexity int, username string, password string, rootPath string) int
RegisterUser func(childComplexity int, username string, password string, rootPath string) int
ScanAll func(childComplexity int) int
@ -170,6 +171,7 @@ type MutationResolver interface {
ScanUser(ctx context.Context, userID int) (*models.ScannerResult, error)
ShareAlbum(ctx context.Context, albumID int, expire *time.Time, password *string) (*models.ShareToken, error)
SharePhoto(ctx context.Context, photoID int, expire *time.Time, password *string) (*models.ShareToken, error)
DeleteShareToken(ctx context.Context, token string) (*models.ShareToken, error)
}
type PhotoResolver interface {
Thumbnail(ctx context.Context, obj *models.Photo) (*models.PhotoURL, error)
@ -317,6 +319,18 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in
return e.complexity.Mutation.AuthorizeUser(childComplexity, args["username"].(string), args["password"].(string)), true
case "Mutation.deleteShareToken":
if e.complexity.Mutation.DeleteShareToken == nil {
break
}
args, err := ec.field_Mutation_deleteShareToken_args(context.TODO(), rawArgs)
if err != nil {
return 0, false
}
return e.complexity.Mutation.DeleteShareToken(childComplexity, args["token"].(string)), true
case "Mutation.initialSetupWizard":
if e.complexity.Mutation.InitialSetupWizard == nil {
break
@ -875,6 +889,8 @@ type Mutation {
shareAlbum(albumId: Int!, expire: Time, password: String): ShareToken
"Generate share token for photo"
sharePhoto(photoId: Int!, expire: Time, password: String): ShareToken
"Delete a share token by it's token value"
deleteShareToken(token: String!): ShareToken
}
type AuthorizeResult {
@ -1050,6 +1066,20 @@ func (ec *executionContext) field_Mutation_authorizeUser_args(ctx context.Contex
return args, nil
}
func (ec *executionContext) field_Mutation_deleteShareToken_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) {
var err error
args := map[string]interface{}{}
var arg0 string
if tmp, ok := rawArgs["token"]; ok {
arg0, err = ec.unmarshalNString2string(ctx, tmp)
if err != nil {
return nil, err
}
}
args["token"] = arg0
return args, nil
}
func (ec *executionContext) field_Mutation_initialSetupWizard_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) {
var err error
args := map[string]interface{}{}
@ -2064,6 +2094,47 @@ func (ec *executionContext) _Mutation_sharePhoto(ctx context.Context, field grap
return ec.marshalOShareToken2ᚖgithubᚗcomᚋviktorstrateᚋphotoviewᚋapiᚋgraphqlᚋmodelsᚐShareToken(ctx, field.Selections, res)
}
func (ec *executionContext) _Mutation_deleteShareToken(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) {
ctx = ec.Tracer.StartFieldExecution(ctx, field)
defer func() {
if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
ret = graphql.Null
}
ec.Tracer.EndFieldExecution(ctx)
}()
rctx := &graphql.ResolverContext{
Object: "Mutation",
Field: field,
Args: nil,
IsMethod: true,
}
ctx = graphql.WithResolverContext(ctx, rctx)
rawArgs := field.ArgumentMap(ec.Variables)
args, err := ec.field_Mutation_deleteShareToken_args(ctx, rawArgs)
if err != nil {
ec.Error(ctx, err)
return graphql.Null
}
rctx.Args = args
ctx = ec.Tracer.StartFieldResolverExecution(ctx, rctx)
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
ctx = rctx // use context from middleware stack in children
return ec.resolvers.Mutation().DeleteShareToken(rctx, args["token"].(string))
})
if err != nil {
ec.Error(ctx, err)
return graphql.Null
}
if resTmp == nil {
return graphql.Null
}
res := resTmp.(*models.ShareToken)
rctx.Result = res
ctx = ec.Tracer.StartFieldChildExecution(ctx)
return ec.marshalOShareToken2ᚖgithubᚗcomᚋviktorstrateᚋphotoviewᚋapiᚋgraphqlᚋmodelsᚐShareToken(ctx, field.Selections, res)
}
func (ec *executionContext) _Photo_id(ctx context.Context, field graphql.CollectedField, obj *models.Photo) (ret graphql.Marshaler) {
ctx = ec.Tracer.StartFieldExecution(ctx, field)
defer func() {
@ -5328,6 +5399,8 @@ func (ec *executionContext) _Mutation(ctx context.Context, sel ast.SelectionSet)
out.Values[i] = ec._Mutation_shareAlbum(ctx, field)
case "sharePhoto":
out.Values[i] = ec._Mutation_sharePhoto(ctx, field)
case "deleteShareToken":
out.Values[i] = ec._Mutation_deleteShareToken(ctx, field)
default:
panic("unknown field " + strconv.Quote(field.Name))
}

View File

@ -58,9 +58,12 @@ func (r *Resolver) Photo() api.PhotoResolver {
}
func (r *photoResolver) Shares(ctx context.Context, obj *models.Photo) ([]*models.ShareToken, error) {
log.Println("Photo: shares not implemented")
shares := make([]*models.ShareToken, 0)
return shares, nil
rows, err := r.Database.Query("SELECT * FROM share_token WHERE photo_id = ?", obj.PhotoID)
if err != nil {
return nil, err
}
return models.NewShareTokensFromRows(rows)
}
func (r *photoResolver) Downloads(ctx context.Context, obj *models.Photo) ([]*models.PhotoDownload, error) {

View File

@ -3,7 +3,7 @@ package resolvers
import (
"context"
"database/sql"
"log"
"errors"
"time"
api "github.com/viktorstrate/photoview/api/graphql"
@ -60,7 +60,7 @@ func (r *queryResolver) ShareToken(ctx context.Context, token string, password *
result, err := models.NewShareTokenFromRow(row)
if err != nil {
if err == sql.ErrNoRows {
return nil, nil
return nil, errors.New("share not found")
} else {
return nil, err
}
@ -69,13 +69,6 @@ func (r *queryResolver) ShareToken(ctx context.Context, token string, password *
return result, nil
}
func (r *queryResolver) PhotoShares(ctx context.Context, token string, password *string) ([]*models.ShareToken, error) {
log.Println("Query PhotoShares: not implemented")
tokens := make([]*models.ShareToken, 0)
return tokens, nil
}
func (r *mutationResolver) ShareAlbum(ctx context.Context, albumID int, expire *time.Time, password *string) (*models.ShareToken, error) {
user := auth.UserFromContext(ctx)
if user == nil {
@ -124,5 +117,73 @@ func (r *mutationResolver) ShareAlbum(ctx context.Context, albumID int, expire *
}
func (r *mutationResolver) SharePhoto(ctx context.Context, photoID int, expire *time.Time, password *string) (*models.ShareToken, error) {
panic("not implemented")
user := auth.UserFromContext(ctx)
if user == nil {
return nil, auth.ErrUnauthorized
}
rows, err := r.Database.Query("SELECT owner_id FROM album, photo WHERE photo.photo_id = ? AND photo.album_id = album.album_id AND album.owner_id = ?", photoID, user.UserID)
if err != nil {
return nil, err
}
if rows.Next() == false {
return nil, auth.ErrUnauthorized
}
rows.Close()
var hashed_password *string = nil
if password != nil {
hashedPassBytes, err := bcrypt.GenerateFromPassword([]byte(*password), 12)
if err != nil {
return nil, err
}
hashed_str := string(hashedPassBytes)
hashed_password = &hashed_str
}
token := utils.GenerateToken()
res, err := r.Database.Exec("INSERT INTO share_token (value, owner_id, expire, password, photo_id) VALUES (?, ?, ?, ?, ?)", token, user.UserID, expire, hashed_password, photoID)
if err != nil {
return nil, err
}
token_id, err := res.LastInsertId()
if err != nil {
return nil, err
}
return &models.ShareToken{
TokenID: int(token_id),
Value: token,
OwnerID: user.UserID,
Expire: expire,
Password: password,
AlbumID: nil,
PhotoID: &photoID,
}, nil
}
func (r *mutationResolver) DeleteShareToken(ctx context.Context, tokenValue string) (*models.ShareToken, error) {
user := auth.UserFromContext(ctx)
if user == nil {
return nil, auth.ErrUnauthorized
}
row := r.Database.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)
if err != nil {
return nil, err
}
if _, err := r.Database.Exec("DELETE FROM share_token WHERE token_id = ?", token.TokenID); err != nil {
return nil, err
}
return token, nil
}

View File

@ -61,6 +61,8 @@ type Mutation {
shareAlbum(albumId: Int!, expire: Time, password: String): ShareToken
"Generate share token for photo"
sharePhoto(photoId: Int!, expire: Time, password: String): ShareToken
"Delete a share token by it's token value"
deleteShareToken(token: String!): ShareToken
}
type AuthorizeResult {

View File

@ -20,7 +20,7 @@ const AlbumSharePage = ({ photo }) => {
<>
<h1>{photo.title}</h1>
<DisplayPhoto
src={photo.original.url}
src={photo.highRes.url}
onLoad={() => {
updateSidebar(<PhotoSidebar photo={photo} hidePreview />)
}}

View File

@ -44,7 +44,7 @@ const addAlbumShareMutation = gql`
`
const deleteShareMutation = gql`
mutation sidebareDeleteShare($token: ID!) {
mutation sidebareDeleteShare($token: String!) {
deleteShareToken(token: $token) {
token
}