@@ -319,14 +319,6 @@ func (m *mgr) isProjectAdmin(u *userpb.User, path string) bool {
319
319
if g == adminGroup {
320
320
// User belongs to the admin group, list all shares for the resource
321
321
322
- // TODO: this only works if shares for a single project are requested.
323
- // If shares for multiple projects are requested, then we're not checking if the
324
- // user is an admin for all of those. We can append the query ` or uid_owner=?`
325
- // for all the project owners, which works fine for new reva
326
- // but won't work for revaold since there, we store the uid of the share creator as uid_owner.
327
- // For this to work across the two versions, this change would have to be made in revaold
328
- // but it won't be straightforward as there, the storage provider doesn't return the
329
- // resource owners.
330
322
return true
331
323
}
332
324
}
@@ -364,65 +356,67 @@ func (m *mgr) ListShares(ctx context.Context, filters []*collaboration.Filter) (
364
356
func (m * mgr ) ListReceivedShares (ctx context.Context , filters []* collaboration.Filter ) ([]* collaboration.ReceivedShare , error ) {
365
357
user := appctx .ContextMustGetUser (ctx )
366
358
367
- query := m .db .Model (& model.Share {}).
368
- Where ("orphan = ?" , false )
359
+ // We need to do this to parse the result
360
+ // Normally, GORM would be able to fill in the Share that is referenced in ShareState
361
+ // However, in GORM's docs: "Join Preload will loads association data using left join"
362
+ // Because we do a RIGHT JOIN, GORM cannot load the data into shareState.Share (in case that ShareState is empty)
363
+ // So we load them both separately, and then set ShareState.Share = Share ourselves
364
+ var results []struct {
365
+ model.ShareState
366
+ model.Share
367
+ }
368
+
369
+ query := m .db .Model (& model.ShareState {}).
370
+ Select ("share_states.*, shares.*" ).
371
+ Joins ("RIGHT OUTER JOIN shares ON shares.id = share_states.share_id" ).
372
+ Where ("shares.orphan = ?" , false )
369
373
370
374
// Also search by all the groups the user is a member of
371
- innerQuery := m .db .Where ("share_with = ? and shared_with_is_group = ?" , user .Username , false )
375
+ innerQuery := m .db .Where ("shares. share_with = ? and shares. shared_with_is_group = ?" , user .Username , false )
372
376
for _ , group := range user .Groups {
373
- innerQuery = innerQuery .Or ("share_with = ? and shared_with_is_group = ?" , group , true )
377
+ innerQuery = innerQuery .Or ("shares. share_with = ? and shares. shared_with_is_group = ?" , group , true )
374
378
}
375
379
query = query .Where (innerQuery )
376
380
377
381
// Append filters
378
382
m .appendFiltersToQuery (query , filters )
379
383
380
- // Get the shares
381
- var shares []model.Share
382
- res := query .Find (& shares )
384
+ // Get the shares + states
385
+ res := query .Find (& results )
383
386
if res .Error != nil {
384
387
return nil , res .Error
385
388
}
386
389
387
- // Now that we have the shares, we fetch the share state for every share
388
390
var receivedShares []* collaboration.ReceivedShare
389
391
390
- for _ , s := range shares {
391
- shareId := & collaboration.ShareId {
392
- OpaqueId : strconv .FormatUint (uint64 (s .ID ), 10 ),
393
- }
394
- shareState , err := m .getShareState (ctx , shareId , user )
395
- if err != nil {
396
- return nil , err
397
- }
398
-
399
- granteeType , _ := m .getUserType (ctx , s .ShareWith )
392
+ // Now we parse everything into the CS3 definition of a CS3ReceivedShare
393
+ for _ , res := range results {
394
+ shareState := res .ShareState
395
+ shareState .Share = res .Share
396
+ granteeType , _ := m .getUserType (ctx , res .Share .ShareWith )
400
397
401
- receivedShares = append (receivedShares , s . AsCS3ReceivedShare (shareState , granteeType ))
398
+ receivedShares = append (receivedShares , res . Share . AsCS3ReceivedShare (& shareState , granteeType ))
402
399
}
403
400
404
401
return receivedShares , nil
405
402
}
406
403
407
- func (m * mgr ) getShareState (ctx context.Context , shareId * collaboration.ShareId , user * userpb.User ) (* model.ShareState , error ) {
404
+ // shareId *collaboration.ShareId
405
+ func (m * mgr ) getShareState (ctx context.Context , share * model.Share , user * userpb.User ) (* model.ShareState , error ) {
408
406
var shareState model.ShareState
409
407
query := m .db .Model (& shareState ).
410
- Where ("share_id = ?" , shareId . OpaqueId ).
408
+ Where ("share_id = ?" , share . ID ).
411
409
Where ("user = ?" , user .Username )
412
410
413
411
res := query .First (& shareState )
414
412
415
413
if res .RowsAffected == 0 {
416
- shareIdInt , err := strconv .Atoi (shareId .OpaqueId )
417
- if err != nil {
418
- return nil , errors .New ("Failed to fetch shareState, and failed to create one (share_id is not an int)" )
419
- }
420
414
// If no share state has been created yet, we create it now using these defaults
421
415
shareState = model.ShareState {
422
- ShareID : uint ( shareIdInt ) ,
423
- Hidden : false ,
424
- Synced : false ,
425
- User : user .Username ,
416
+ Share : * share ,
417
+ Hidden : false ,
418
+ Synced : false ,
419
+ User : user .Username ,
426
420
}
427
421
// Does not really matter if it fails, next time the user
428
422
// lists his shares this will just be called again
@@ -439,7 +433,7 @@ func (m *mgr) getReceivedByID(ctx context.Context, id *collaboration.ShareId, gt
439
433
return nil , err
440
434
}
441
435
442
- shareState , err := m .getShareState (ctx , id , user )
436
+ shareState , err := m .getShareState (ctx , share , user )
443
437
if err != nil {
444
438
return nil , err
445
439
}
@@ -455,11 +449,7 @@ func (m *mgr) getReceivedByKey(ctx context.Context, key *collaboration.ShareKey,
455
449
return nil , err
456
450
}
457
451
458
- shareId := & collaboration.ShareId {
459
- OpaqueId : strconv .Itoa (int (share .ID )),
460
- }
461
-
462
- shareState , err := m .getShareState (ctx , shareId , user )
452
+ shareState , err := m .getShareState (ctx , share , user )
463
453
if err != nil {
464
454
return nil , err
465
455
}
@@ -496,12 +486,23 @@ func (m *mgr) UpdateReceivedShare(ctx context.Context, share *collaboration.Rece
496
486
497
487
user := appctx .ContextMustGetUser (ctx )
498
488
499
- rs , err := m .GetReceivedShare (ctx , & collaboration.ShareReference {Spec : & collaboration.ShareReference_Id {Id : share .Share .Id }})
489
+ rs , err := m .getReceivedByID (ctx , share .Share .Id , user .Id .Type )
490
+ if err != nil {
491
+ return nil , err
492
+ }
493
+
494
+ shareId , err := strconv .Atoi (share .Share .Id .OpaqueId )
500
495
if err != nil {
501
496
return nil , err
502
497
}
503
498
504
- shareState , err := m .getShareState (ctx , share .Share .Id , user )
499
+ shareState , err := m .getShareState (ctx , & model.Share {
500
+ ProtoShare : model.ProtoShare {
501
+ Model : gorm.Model {
502
+ ID : uint (shareId ),
503
+ },
504
+ },
505
+ }, user )
505
506
if err != nil {
506
507
return nil , err
507
508
}
0 commit comments