diff --git a/changelog/unreleased/additional-share-with.md b/changelog/unreleased/additional-share-with.md new file mode 100644 index 00000000000..86d8432b4be --- /dev/null +++ b/changelog/unreleased/additional-share-with.md @@ -0,0 +1,6 @@ +Enhancement: Render additional share with in ocs sharing api + +Recipients can now be distinguished by their email, which is rendered as additional info in the ocs api for share and file owners as well as share recipients. + +https://github.com/cs3org/reva/pull/1451 +https://github.com/owncloud/ocis/issues/1190 diff --git a/go.mod b/go.mod index 7235eb562b8..194821343db 100644 --- a/go.mod +++ b/go.mod @@ -32,7 +32,6 @@ require ( github.com/mattn/go-sqlite3 v2.0.3+incompatible github.com/mitchellh/copystructure v1.0.0 // indirect github.com/mitchellh/mapstructure v1.4.1 - github.com/oleiade/reflections v1.0.1 // indirect github.com/onsi/ginkgo v1.15.0 github.com/onsi/gomega v1.10.5 github.com/ory/fosite v0.36.1 @@ -45,7 +44,6 @@ require ( github.com/studio-b12/gowebdav v0.0.0-20200303150724-9380631c29a1 github.com/tus/tusd v1.1.1-0.20200416115059-9deabf9d80c2 go.opencensus.io v0.22.6 - golang.org/x/crypto v0.0.0-20201203163018-be400aefbc4c golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d golang.org/x/term v0.0.0-20201117132131-f5c789dd3221 diff --git a/go.sum b/go.sum index 2211f5b0fc1..70461b04fae 100644 --- a/go.sum +++ b/go.sum @@ -72,8 +72,10 @@ github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:l github.com/asaskevich/govalidator v0.0.0-20200428143746-21a406dcc535 h1:4daAzAu0S6Vi7/lbWECcX0j45yZReDZ56BQsrVBOEEY= github.com/asaskevich/govalidator v0.0.0-20200428143746-21a406dcc535/go.mod h1:oGkLhpf+kjZl6xBf758TQhh5XrAeiJv/7FRz/2spLIg= github.com/aws/aws-sdk-go v1.20.1/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= +github.com/aws/aws-sdk-go v1.23.19/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/aws/aws-sdk-go v1.37.3 h1:1f0groABc4AuapskpHf6EBRaG2tqw0Sx3ebCMwfp1Ys= github.com/aws/aws-sdk-go v1.37.3/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro= +github.com/aws/aws-xray-sdk-go v0.9.4/go.mod h1:XtMKdBQfpVut+tJEwI7+dJFRxxRdxHDyVNp2tHXRq04= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973 h1:xJ4a3vCFaGF/jqvzLMYoU8P317H5OQ+Via4RmuPwCS0= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0 h1:HWo1m869IqiPhD389kmkxeTalrjNbbJTC8LXupb+sl0= @@ -132,9 +134,8 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/dgraph-io/ristretto v0.0.1/go.mod h1:T40EBc7CJke8TkpiYfGGKAeFjSaxuFXhuXRyumBd6RE= +github.com/dgraph-io/ristretto v0.0.2 h1:a5WaUrDa0qm0YrAAS1tUykT5El3kt62KNZZeMxQn3po= github.com/dgraph-io/ristretto v0.0.2/go.mod h1:KPxhHT9ZxKefz+PCeOGsrHpl1qZ7i70dGTu2u+Ahh6E= -github.com/dgraph-io/ristretto v0.0.3 h1:jh22xisGBjrEVnRZ1DVTpBVQm0Xndu8sMl0CWDzSIBI= -github.com/dgraph-io/ristretto v0.0.3/go.mod h1:KPxhHT9ZxKefz+PCeOGsrHpl1qZ7i70dGTu2u+Ahh6E= github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2 h1:tdlZCpZ/P9DhczCTSixgIKmwPv6+wP5DGjqLYw5SUiA= @@ -595,8 +596,8 @@ github.com/konsorten/go-windows-terminal-sequences v0.0.0-20180402223658-b729f26 github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/konsorten/go-windows-terminal-sequences v1.0.3 h1:CE8S1cTafDpPvMhIxNJKvHsGVBgn1xWYf1NbHQhywc8= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= @@ -680,8 +681,6 @@ github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh github.com/mitchellh/mapstructure v1.2.2/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/mapstructure v1.3.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/mapstructure v1.3.2/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= -github.com/mitchellh/mapstructure v1.3.3 h1:SzB1nHZ2Xi+17FP0zVQBHIZqvwRN9408fJO8h+eeNA8= -github.com/mitchellh/mapstructure v1.3.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/mapstructure v1.4.1 h1:CpVNEelQCZBooIPDn+AR3NpivK/TIKU8bDxdASFVQag= github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/reflectwalk v1.0.0 h1:9D+8oIskB4VJBN5SFlmc27fSlIBZaov1Wpk/IfikLNY= @@ -741,8 +740,6 @@ github.com/ory/analytics-go/v4 v4.0.0/go.mod h1:FMx9cLRD9xN+XevPvZ5FDMfignpmcqPP github.com/ory/dockertest v3.3.5+incompatible/go.mod h1:1vX4m9wsvi00u5bseYwXaSnhNrne+V0E6LAcBILJdPs= github.com/ory/dockertest/v3 v3.5.4/go.mod h1:J8ZUbNB2FOhm1cFZW9xBpDsODqsSWcyYgtJYVPcnF70= github.com/ory/fosite v0.29.0/go.mod h1:0atSZmXO7CAcs6NPMI/Qtot8tmZYj04Nddoold4S2h0= -github.com/ory/fosite v0.35.1 h1:mGPcwVGwHA7Yy9wr/7LDps6BEXyavL32NxizL9eH53Q= -github.com/ory/fosite v0.35.1/go.mod h1:h+ize9gk0GvRyGjabriqSEmTkMhny+O95cijb8DVqPE= github.com/ory/fosite v0.36.1 h1:xqu4UYemsiKX1LesoYx+3XCs74ZOGDK6bMBSfb4o3iA= github.com/ory/fosite v0.36.1/go.mod h1:42KzCDGR5zzuEIP48QwxL0QkA98ckUphlSgrSvxKB+A= github.com/ory/go-acc v0.0.0-20181118080137-ddc355013f90/go.mod h1:sxnvPCxChFuSmTJGj8FdMupeq1BezCiEpDjTUXQ4hf4= @@ -781,7 +778,6 @@ github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA= -github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI= github.com/pkg/term v1.1.0 h1:xIAAdCMh3QIAy+5FrE8Ad8XoDhEU4ufwbaSozViP9kk= github.com/pkg/term v1.1.0/go.mod h1:E25nymQcrSllhX42Ok8MRm1+hyBdHY0dCeiKZ9jpNGw= github.com/pkg/xattr v0.4.2 h1:fbVxr9lvkToTGgPljVszvFsOdcbSv5BmGABneyxRgZM= @@ -882,9 +878,8 @@ github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72 h1:qLC7fQah7D6K1 github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= github.com/spf13/afero v1.2.0/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= +github.com/spf13/afero v1.2.2 h1:5jhuqJyZCZf2JRofRvN/nIFgIWNzPa3/Vz8mYylgbWc= github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= -github.com/spf13/afero v1.3.2 h1:GDarE4TJQI52kYSbSAmLiId1Elfj+xgSDqrUZxFhxlU= -github.com/spf13/afero v1.3.2/go.mod h1:5KUK8ByomD5Ti5Artl0RtHeI5pTF7MIDuXL3yY520V4= github.com/spf13/cast v1.2.0/go.mod h1:r2rcYCSwa1IExKTDiTfzaxqT2FNHs8hODu4LnUfgKEg= github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cast v1.3.1 h1:nFm6S0SMdyzrzcmThSipiEubIDy8WEXKNZ0UOgiRpng= @@ -956,7 +951,6 @@ github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1: github.com/xtgo/uuid v0.0.0-20140804021211-a0b114877d4c/go.mod h1:UrdRz5enIKZ63MEE3IF9l2/ebyx59GyGgPi+tICQdmM= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q= github.com/ziutek/mymysql v1.5.4/go.mod h1:LMSpPZ6DbqWFxNCHW77HeMg9I646SAhApZ/wKdgO/C0= @@ -1018,8 +1012,6 @@ golang.org/x/crypto v0.0.0-20200323165209-0ec3e9974c59/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200604202706-70a84ac30bf9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20200709230013-948cd5f35899 h1:DZhuSZLsGlFL4CmhA8BcRA0mnthyA/nZ00AqCUo7vHg= -golang.org/x/crypto v0.0.0-20200709230013-948cd5f35899/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201203163018-be400aefbc4c h1:9HhBz5L/UjnK9XLtiZhYAdue5BVKep3PMmS2LuPDt8k= golang.org/x/crypto v0.0.0-20201203163018-be400aefbc4c/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -1183,7 +1175,6 @@ golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200420163511-1957bb5e6d1f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200602225109-6fdc65e7d980/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200720211630-cb9d2d5c5666/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200909081042-eff7692f9009/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200918174421-af09f7315aff/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1270,7 +1261,6 @@ golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapK golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= golang.org/x/tools v0.0.0-20200522201501-cb1345f3a375/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200721223218-6123e77877b2/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210112230658-8b4aab62c064 h1:BmCFkEH4nJrYcAc2L08yX5RhYGD4j58PTMkEUDkpz2I= golang.org/x/tools v0.0.0-20210112230658-8b4aab62c064/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= diff --git a/internal/http/services/owncloud/ocs/conversions/main.go b/internal/http/services/owncloud/ocs/conversions/main.go index 894ef381ef5..0b5e6e142ac 100644 --- a/internal/http/services/owncloud/ocs/conversions/main.go +++ b/internal/http/services/owncloud/ocs/conversions/main.go @@ -163,8 +163,9 @@ type MatchData struct { // MatchValueData holds the type and actual value type MatchValueData struct { - ShareType int `json:"shareType" xml:"shareType"` - ShareWith string `json:"shareWith" xml:"shareWith"` + ShareType int `json:"shareType" xml:"shareType"` + ShareWith string `json:"shareWith" xml:"shareWith"` + ShareWithAdditionalInfo string `json:"shareWithAdditionalInfo" xml:"shareWithAdditionalInfo"` } // UserShare2ShareData converts a cs3api user share into shareData data model @@ -176,6 +177,7 @@ func UserShare2ShareData(ctx context.Context, share *collaboration.Share) (*Shar UIDOwner: LocalUserIDToString(share.GetCreator()), UIDFileOwner: LocalUserIDToString(share.GetOwner()), ShareWith: LocalUserIDToString(share.GetGrantee().GetId()), + // TODO ShareWithAdditionalInfo: } if share.Id != nil && share.Id.OpaqueId != "" { @@ -227,6 +229,7 @@ func PublicShare2ShareData(share *link.PublicShare, r *http.Request, publicURL s } // LocalUserIDToString transforms a cs3api user id into an ocs data model without domain name +// TODO ocs uses user names ... so an additional lookup is needed. see mapUserIds() func LocalUserIDToString(userID *userpb.UserId) string { if userID == nil || userID.OpaqueId == "" { return "" diff --git a/internal/http/services/owncloud/ocs/handlers/apps/sharing/sharees/sharees.go b/internal/http/services/owncloud/ocs/handlers/apps/sharing/sharees/sharees.go index 0a2d0f1408e..45d071599c2 100644 --- a/internal/http/services/owncloud/ocs/handlers/apps/sharing/sharees/sharees.go +++ b/internal/http/services/owncloud/ocs/handlers/apps/sharing/sharees/sharees.go @@ -105,9 +105,9 @@ func (h *Handler) userAsMatch(u *userpb.User) *conversions.MatchData { Label: u.DisplayName, Value: &conversions.MatchValueData{ ShareType: int(conversions.ShareTypeUser), - // TODO(jfd) find more robust userid - // username might be ok as it is unique at a given point in time - ShareWith: u.Username, + // api compatability with oc10: always use the username + ShareWith: u.Username, + ShareWithAdditionalInfo: u.Mail, }, } } diff --git a/internal/http/services/owncloud/ocs/handlers/apps/sharing/shares/public.go b/internal/http/services/owncloud/ocs/handlers/apps/sharing/shares/public.go index 1dbd2582f3f..45550e1a127 100644 --- a/internal/http/services/owncloud/ocs/handlers/apps/sharing/shares/public.go +++ b/internal/http/services/owncloud/ocs/handlers/apps/sharing/shares/public.go @@ -130,7 +130,7 @@ func (h *Handler) createPublicLinkShare(w http.ResponseWriter, r *http.Request, response.WriteOCSError(w, r, response.MetaServerError.StatusCode, "error enhancing response with share data", err) return } - h.addDisplaynames(ctx, c, s) + h.mapUserIds(ctx, c, s) response.WriteOCSSuccess(w, r, s) } @@ -183,7 +183,7 @@ func (h *Handler) listPublicShares(r *http.Request, filters []*link.ListPublicSh log.Debug().Interface("share", share).Interface("info", statResponse.Info).Err(err).Msg("could not add file info, skipping") continue } - h.addDisplaynames(ctx, c, sData) + h.mapUserIds(ctx, c, sData) log.Debug().Interface("share", share).Interface("info", statResponse.Info).Interface("shareData", share).Msg("mapped") @@ -407,7 +407,7 @@ func (h *Handler) updatePublicShare(w http.ResponseWriter, r *http.Request, shar response.WriteOCSError(w, r, response.MetaServerError.StatusCode, "error enhancing response with share data", err) return } - h.addDisplaynames(r.Context(), gwC, s) + h.mapUserIds(r.Context(), gwC, s) response.WriteOCSSuccess(w, r, s) } diff --git a/internal/http/services/owncloud/ocs/handlers/apps/sharing/shares/shares.go b/internal/http/services/owncloud/ocs/handlers/apps/sharing/shares/shares.go index bcb93e16f4a..3e3e197e160 100644 --- a/internal/http/services/owncloud/ocs/handlers/apps/sharing/shares/shares.go +++ b/internal/http/services/owncloud/ocs/handlers/apps/sharing/shares/shares.go @@ -51,19 +51,24 @@ import ( // Handler implements the shares part of the ownCloud sharing API type Handler struct { - gatewayAddr string - publicURL string - sharePrefix string - displayNameCache *ttlmap.TTLMap - userNameCache *ttlmap.TTLMap + gatewayAddr string + publicURL string + sharePrefix string + userIdentifierCache *ttlmap.TTLMap +} + +// we only cache the minimal set of data instead of the full user metadata +type userIdentifiers struct { + DisplayName string + UserName string + Mail string } // Init initializes this and any contained handlers func (h *Handler) Init(c *config.Config) error { h.gatewayAddr = c.GatewaySvc h.publicURL = c.Config.Host - h.displayNameCache = ttlmap.New(1000, 60) - h.userNameCache = ttlmap.New(1000, 60) + h.userIdentifierCache = ttlmap.New(1000, 60) h.sharePrefix = c.SharePrefix return nil } @@ -392,7 +397,6 @@ func (h *Handler) getShare(w http.ResponseWriter, r *http.Request, shareID strin log.Error().Err(err).Str("status", statResponse.Status.Code.String()).Msg("error mapping share data") response.WriteOCSError(w, r, response.MetaServerError.StatusCode, "error mapping share data", err) } - h.addDisplaynames(ctx, client, share) h.mapUserIds(ctx, client, share) response.WriteOCSSuccess(w, r, []*conversions.ShareData{share}) @@ -516,7 +520,6 @@ func (h *Handler) updateShare(w http.ResponseWriter, r *http.Request, shareID st response.WriteOCSError(w, r, response.MetaServerError.StatusCode, err.Error(), err) return } - h.addDisplaynames(ctx, uClient, share) h.mapUserIds(ctx, uClient, share) response.WriteOCSSuccess(w, r, share) @@ -681,7 +684,6 @@ func (h *Handler) listSharesWithMe(w http.ResponseWriter, r *http.Request) { log.Debug().Interface("received_share", rs).Interface("info", info).Interface("shareData", data).Err(err).Msg("could not add file info, skipping") continue } - h.addDisplaynames(r.Context(), gwc, data) h.mapUserIds(r.Context(), gwc, data) if data.State == ocsStateAccepted { @@ -871,126 +873,80 @@ func (h *Handler) addFileInfo(ctx context.Context, s *conversions.ShareData, inf return nil } -func (h *Handler) getDisplayname(ctx context.Context, c gateway.GatewayAPIClient, userid string) string { - log := appctx.GetLogger(ctx) +// mustGetUserIdentifiers always returns a struct with identifiers, if the user could not be found they will all be empty +func (h *Handler) mustGetUserIdentifiers(ctx context.Context, c gateway.GatewayAPIClient, userid string) *userIdentifiers { + sublog := appctx.GetLogger(ctx).With().Str("userid", userid).Logger() if userid == "" { - return "" + return &userIdentifiers{} } - if dn := h.displayNameCache.Get(userid); dn != "" { - log.Debug().Str("userid", userid).Msg("cache hit") - return dn + //item := h.userIdentifierCache.Get(userid) + ui, ok := h.userIdentifierCache.Get(userid).(*userIdentifiers) + if ok { + sublog.Debug().Msg("cache hit") + return ui } - log.Debug().Str("userid", userid).Msg("cache miss") + sublog.Debug().Msg("cache miss") res, err := c.GetUser(ctx, &userpb.GetUserRequest{ UserId: &userpb.UserId{ OpaqueId: userid, }, }) if err != nil { - log.Err(err). - Str("userid", userid). - Msg("could not look up user") - return "" + sublog.Err(err).Msg("could not look up user") + return &userIdentifiers{} } if res.GetStatus().GetCode() != rpc.Code_CODE_OK { - log.Err(err). - Str("opaque_id", userid). + sublog.Err(err). Int32("code", int32(res.GetStatus().GetCode())). Str("message", res.GetStatus().GetMessage()). Msg("get user call failed") - return "" + return &userIdentifiers{} } if res.User == nil { - log.Debug(). - Str("opaque_id", userid). + sublog.Debug(). Int32("code", int32(res.GetStatus().GetCode())). Str("message", res.GetStatus().GetMessage()). Msg("user not found") - return "" - } - if res.User.DisplayName == "" { - log.Debug(). - Str("opaque_id", userid). - Int32("code", int32(res.GetStatus().GetCode())). - Str("message", res.GetStatus().GetMessage()). - Msg("Displayname empty") - return "" + return &userIdentifiers{} } - h.displayNameCache.Put(userid, res.User.DisplayName) - h.userNameCache.Put(userid, res.User.Username) - log.Debug().Str("userid", userid).Msg("cache update") - return res.User.DisplayName -} - -func (h *Handler) getUsername(ctx context.Context, c gateway.GatewayAPIClient, userid string) string { - log := appctx.GetLogger(ctx) - if userid == "" { - return "" - } - if un := h.userNameCache.Get(userid); un != "" { - log.Debug().Str("userid", userid).Msg("cache hit") - return un - } - log.Debug().Str("userid", userid).Msg("cache miss") - res, err := c.GetUser(ctx, &userpb.GetUserRequest{ - UserId: &userpb.UserId{ - OpaqueId: userid, - }, - }) - if err != nil { - log.Err(err). - Str("userid", userid). - Msg("could not look up user") - return "" - } - if res.GetStatus().GetCode() != rpc.Code_CODE_OK { - log.Err(err). - Str("opaque_id", userid). - Int32("code", int32(res.GetStatus().GetCode())). - Str("message", res.GetStatus().GetMessage()). - Msg("get user call failed") - return "" - } - if res.User == nil { - log.Debug(). - Str("opaque_id", userid). - Int32("code", int32(res.GetStatus().GetCode())). - Str("message", res.GetStatus().GetMessage()). - Msg("user not found") - return "" - } - if res.User.Username == "" { - log.Debug(). - Str("opaque_id", userid). - Int32("code", int32(res.GetStatus().GetCode())). - Str("message", res.GetStatus().GetMessage()). - Msg("Username empty") - return "" + ui = &userIdentifiers{ + DisplayName: res.User.DisplayName, + UserName: res.User.Username, + Mail: res.User.Mail, } - - h.userNameCache.Put(userid, res.User.Username) - h.displayNameCache.Put(userid, res.User.DisplayName) + h.userIdentifierCache.Put(userid, ui) log.Debug().Str("userid", userid).Msg("cache update") - return res.User.Username + return ui } -func (h *Handler) addDisplaynames(ctx context.Context, c gateway.GatewayAPIClient, s *conversions.ShareData) { +func (h *Handler) mapUserIds(ctx context.Context, c gateway.GatewayAPIClient, s *conversions.ShareData) { + owner := h.mustGetUserIdentifiers(ctx, c, s.UIDOwner) + s.UIDOwner = owner.UserName if s.DisplaynameOwner == "" { - s.DisplaynameOwner = h.getDisplayname(ctx, c, s.UIDOwner) + s.DisplaynameOwner = owner.DisplayName + } + if s.AdditionalInfoFileOwner == "" { + s.AdditionalInfoFileOwner = owner.Mail } + + fileOwner := h.mustGetUserIdentifiers(ctx, c, s.UIDFileOwner) + s.UIDFileOwner = fileOwner.UserName if s.DisplaynameFileOwner == "" { - s.DisplaynameFileOwner = h.getDisplayname(ctx, c, s.UIDFileOwner) + s.DisplaynameFileOwner = fileOwner.DisplayName } - if s.ShareWithDisplayname == "" { - s.ShareWithDisplayname = h.getDisplayname(ctx, c, s.ShareWith) + if s.AdditionalInfoOwner == "" { + s.AdditionalInfoOwner = fileOwner.Mail } -} -func (h *Handler) mapUserIds(ctx context.Context, c gateway.GatewayAPIClient, s *conversions.ShareData) { - s.UIDOwner = h.getUsername(ctx, c, s.UIDOwner) - s.UIDFileOwner = h.getUsername(ctx, c, s.UIDFileOwner) - s.ShareWith = h.getUsername(ctx, c, s.ShareWith) + shareWith := h.mustGetUserIdentifiers(ctx, c, s.ShareWith) + s.ShareWith = shareWith.UserName + if s.ShareWithDisplayname == "" { + s.ShareWithDisplayname = shareWith.DisplayName + } + if s.ShareWithAdditionalInfo == "" { + s.ShareWithAdditionalInfo = shareWith.Mail + } } func parseTimestamp(timestampString string) (*types.Timestamp, error) { diff --git a/internal/http/services/owncloud/ocs/handlers/apps/sharing/shares/user.go b/internal/http/services/owncloud/ocs/handlers/apps/sharing/shares/user.go index 3ce051d7881..1ea53811dfd 100644 --- a/internal/http/services/owncloud/ocs/handlers/apps/sharing/shares/user.go +++ b/internal/http/services/owncloud/ocs/handlers/apps/sharing/shares/user.go @@ -154,7 +154,6 @@ func (h *Handler) createUserShare(w http.ResponseWriter, r *http.Request, statIn response.WriteOCSError(w, r, response.MetaServerError.StatusCode, "error adding fileinfo to share", err) return } - h.addDisplaynames(ctx, c, s) h.mapUserIds(ctx, c, s) response.WriteOCSSuccess(w, r, s) @@ -246,7 +245,6 @@ func (h *Handler) listUserShares(r *http.Request, filters []*collaboration.ListS log.Debug().Interface("share", s).Interface("info", statResponse.Info).Interface("shareData", data).Err(err).Msg("could not add file info, skipping") continue } - h.addDisplaynames(ctx, c, data) h.mapUserIds(ctx, c, data) log.Debug().Interface("share", s).Interface("info", rInfo).Interface("shareData", data).Msg("mapped") diff --git a/pkg/ttlmap/ttlmap.go b/pkg/ttlmap/ttlmap.go index 1867492cd0e..30fa17a0eaf 100644 --- a/pkg/ttlmap/ttlmap.go +++ b/pkg/ttlmap/ttlmap.go @@ -31,7 +31,7 @@ type TTLMap struct { } type item struct { - value string + value interface{} lastAccess int64 } @@ -58,7 +58,7 @@ func (m *TTLMap) Len() int { } // Put sets or overwrites an item, resetting the ttl -func (m *TTLMap) Put(k, v string) { +func (m *TTLMap) Put(k string, v interface{}) { m.l.Lock() it, ok := m.m[k] if !ok { @@ -70,7 +70,7 @@ func (m *TTLMap) Put(k, v string) { } // Get retrieves an item from the cache, resetting the ttl -func (m *TTLMap) Get(k string) (v string) { +func (m *TTLMap) Get(k string) (v interface{}) { m.l.Lock() if it, ok := m.m[k]; ok { v = it.value