@@ -47,7 +47,8 @@ import (
47
47
)
48
48
49
49
const (
50
- versionPrefix = ".sys.v#."
50
+ versionPrefix = ".sys.v#."
51
+ favoritesKey = "http://owncloud.org/ns/favorite"
51
52
)
52
53
53
54
const (
@@ -57,6 +58,29 @@ const (
57
58
UserAttr
58
59
)
59
60
61
+ func serializeAttribute (a * eosclient.Attribute ) string {
62
+ return fmt .Sprintf ("%s.%s=%s" , attrTypeToString (a .Type ), a .Key , a .Val )
63
+ }
64
+
65
+ func attrTypeToString (at eosclient.AttrType ) string {
66
+ switch at {
67
+ case eosclient .SystemAttr :
68
+ return "sys"
69
+ case eosclient .UserAttr :
70
+ return "user"
71
+ default :
72
+ return "invalid"
73
+ }
74
+ }
75
+
76
+ func isValidAttribute (a * eosclient.Attribute ) bool {
77
+ // validate that an attribute is correct.
78
+ if (a .Type != eosclient .SystemAttr && a .Type != eosclient .UserAttr ) || a .Key == "" {
79
+ return false
80
+ }
81
+ return true
82
+ }
83
+
60
84
// Options to configure the Client.
61
85
type Options struct {
62
86
@@ -483,6 +507,22 @@ func (c *Client) fixupACLs(ctx context.Context, auth eosclient.Authorization, in
483
507
484
508
// SetAttr sets an extended attributes on a path.
485
509
func (c * Client ) SetAttr (ctx context.Context , auth eosclient.Authorization , attr * eosclient.Attribute , errorIfExists , recursive bool , path , app string ) error {
510
+ if ! isValidAttribute (attr ) {
511
+ return errors .New ("eos: attr is invalid: " + serializeAttribute (attr ))
512
+ }
513
+
514
+ // Favorites need to be stored per user so handle these separately
515
+ if attr .Type == eosclient .UserAttr && attr .Key == favoritesKey {
516
+ info , err := c .GetFileInfoByPath (ctx , auth , path )
517
+ if err != nil {
518
+ return err
519
+ }
520
+ return c .handleFavAttr (ctx , auth , attr , recursive , path , info , true )
521
+ }
522
+ return c .setEOSAttr (ctx , auth , attr , errorIfExists , recursive , path , app )
523
+ }
524
+
525
+ func (c * Client ) setEOSAttr (ctx context.Context , auth eosclient.Authorization , attr * eosclient.Attribute , errorIfExists , recursive bool , path , app string ) error {
486
526
log := appctx .GetLogger (ctx )
487
527
log .Info ().Str ("func" , "SetAttr" ).Str ("uid,gid" , auth .Role .UID + "," + auth .Role .GID ).Str ("path" , path ).Msg ("" )
488
528
@@ -531,6 +571,32 @@ func (c *Client) SetAttr(ctx context.Context, auth eosclient.Authorization, attr
531
571
return err
532
572
}
533
573
574
+ func (c * Client ) handleFavAttr (ctx context.Context , auth eosclient.Authorization , attr * eosclient.Attribute , recursive bool , path string , info * eosclient.FileInfo , set bool ) error {
575
+ var err error
576
+ u := appctx .ContextMustGetUser (ctx )
577
+ if info == nil {
578
+ info , err = c .GetFileInfoByPath (ctx , auth , path )
579
+ if err != nil {
580
+ return err
581
+ }
582
+ }
583
+ favStr := info .Attrs [favoritesKey ]
584
+ favs , err := acl .Parse (favStr , acl .ShortTextForm )
585
+ if err != nil {
586
+ return err
587
+ }
588
+ if set {
589
+ err = favs .SetEntry (acl .TypeUser , u .Id .OpaqueId , "1" )
590
+ if err != nil {
591
+ return err
592
+ }
593
+ } else {
594
+ favs .DeleteEntry (acl .TypeUser , u .Id .OpaqueId )
595
+ }
596
+ attr .Val = favs .Serialize ()
597
+ return c .setEOSAttr (ctx , auth , attr , false , recursive , path , "" )
598
+ }
599
+
534
600
// UnsetAttr unsets an extended attribute on a path.
535
601
func (c * Client ) UnsetAttr (ctx context.Context , auth eosclient.Authorization , attr * eosclient.Attribute , recursive bool , path , app string ) error {
536
602
log := appctx .GetLogger (ctx )
0 commit comments