diff --git a/.golangci.yaml b/.golangci.yaml index 019e7d5a9a5..8354f33902f 100644 --- a/.golangci.yaml +++ b/.golangci.yaml @@ -4,11 +4,7 @@ issues: text: "SA1019:" linters: - staticcheck - - path: pkg/publicshare/manager/json/json.go - text: "SA1019:" - linters: - - staticcheck - - path: internal/grpc/services/gateway/publicshareprovider.go + - path: pkg/utils/utils.go text: "SA1019:" linters: - staticcheck diff --git a/Makefile b/Makefile index 1c4a41517ad..374b0e756de 100644 --- a/Makefile +++ b/Makefile @@ -48,7 +48,7 @@ contrib: # for manual building only deps: - cd /tmp && rm -rf golangci-lint && git clone --quiet -b 'v1.26.0' --single-branch --depth 1 https://github.com/golangci/golangci-lint &> /dev/null && cd golangci-lint/cmd/golangci-lint && go install + cd /tmp && rm -rf golangci-lint && git clone --quiet -b 'v1.38.0' --single-branch --depth 1 https://github.com/golangci/golangci-lint &> /dev/null && cd golangci-lint/cmd/golangci-lint && go install cd /tmp && go get golang.org/x/tools/cmd/goimports build-ci: off diff --git a/changelog/unreleased/ocm-find-accepted-users.md b/changelog/unreleased/ocm-find-accepted-users.md new file mode 100644 index 00000000000..c9365e4f59a --- /dev/null +++ b/changelog/unreleased/ocm-find-accepted-users.md @@ -0,0 +1,3 @@ +Enhancement: Add FindAcceptedUsers method to OCM Invite API + +https://github.com/cs3org/reva/pull/1527 diff --git a/cmd/reva/main.go b/cmd/reva/main.go index 5f851cc490c..e349a09ab7e 100644 --- a/cmd/reva/main.go +++ b/cmd/reva/main.go @@ -55,6 +55,7 @@ var ( rmCommand(), moveCommand(), mkdirCommand(), + ocmFindAcceptedUsersCommand(), ocmShareCreateCommand(), ocmShareListCommand(), ocmShareRemoveCommand(), diff --git a/cmd/reva/ocm-find-accepted-users.go b/cmd/reva/ocm-find-accepted-users.go new file mode 100644 index 00000000000..5445f9f6580 --- /dev/null +++ b/cmd/reva/ocm-find-accepted-users.go @@ -0,0 +1,79 @@ +// Copyright 2018-2021 CERN +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// In applying this license, CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +package main + +import ( + "encoding/gob" + "io" + "os" + + invitepb "github.com/cs3org/go-cs3apis/cs3/ocm/invite/v1beta1" + rpc "github.com/cs3org/go-cs3apis/cs3/rpc/v1beta1" + "github.com/jedib0t/go-pretty/table" +) + +func ocmFindAcceptedUsersCommand() *command { + cmd := newCommand("ocm-find-accepted-users") + cmd.Description = func() string { return "find remote users who have accepted invite tokens by their attributes" } + cmd.Usage = func() string { return "Usage: ocm-find-accepted-users " } + + cmd.Action = func(w ...io.Writer) error { + var filter string + if cmd.NArg() == 1 { + filter = cmd.Args()[0] + } + + ctx := getAuthContext() + client, err := getClient() + if err != nil { + return err + } + + acceptedUsersRes, err := client.FindAcceptedUsers(ctx, &invitepb.FindAcceptedUsersRequest{ + Filter: filter, + }) + if err != nil { + return err + } + if acceptedUsersRes.Status.Code != rpc.Code_CODE_OK { + return formatError(acceptedUsersRes.Status) + } + + if len(w) == 0 { + t := table.NewWriter() + t.SetOutputMirror(os.Stdout) + t.AppendHeader(table.Row{"OpaqueId", "Idp", "Mail", "DisplayName"}) + + for _, u := range acceptedUsersRes.AcceptedUsers { + t.AppendRows([]table.Row{ + {u.Id.OpaqueId, u.Id.Idp, u.Mail, u.DisplayName}, + }) + } + t.Render() + } else { + enc := gob.NewEncoder(w[0]) + if err := enc.Encode(acceptedUsersRes.AcceptedUsers); err != nil { + return err + } + } + + return nil + } + return cmd +} diff --git a/cmd/reva/ocm-share-create.go b/cmd/reva/ocm-share-create.go index b073eeedbcc..aa83d578576 100644 --- a/cmd/reva/ocm-share-create.go +++ b/cmd/reva/ocm-share-create.go @@ -19,7 +19,6 @@ package main import ( - "fmt" "io" "os" "strconv" @@ -39,7 +38,7 @@ import ( func ocmShareCreateCommand() *command { cmd := newCommand("ocm-share-create") cmd.Description = func() string { return "create OCM share to a user or group" } - cmd.Usage = func() string { return "Usage: ocm-share create [-flags] " } + cmd.Usage = func() string { return "Usage: ocm-share-create [-flags] " } grantType := cmd.String("type", "user", "grantee type (user or group)") grantee := cmd.String("grantee", "", "the grantee") idp := cmd.String("idp", "", "the idp of the grantee, default to same idp as the user triggering the action") @@ -78,7 +77,7 @@ func ocmShareCreateCommand() *command { return err } - remoteUserRes, err := client.GetRemoteUser(ctx, &invitepb.GetRemoteUserRequest{ + remoteUserRes, err := client.GetAcceptedUser(ctx, &invitepb.GetAcceptedUserRequest{ RemoteUserId: &userpb.UserId{OpaqueId: *grantee, Idp: *idp}, }) if err != nil { @@ -148,7 +147,6 @@ func ocmShareCreateCommand() *command { return formatError(shareRes.Status) } - fmt.Println("create share done") t := table.NewWriter() t.SetOutputMirror(os.Stdout) t.AppendHeader(table.Row{"#", "Owner.Idp", "Owner.OpaqueId", "ResourceId", "Permissions", "Type", "Grantee.Idp", "Grantee.OpaqueId", "Created", "Updated"}) diff --git a/cmd/revad/runtime/runtime.go b/cmd/revad/runtime/runtime.go index cd5b7f7c742..7c7e6a6e232 100644 --- a/cmd/revad/runtime/runtime.go +++ b/cmd/revad/runtime/runtime.go @@ -144,7 +144,7 @@ func initCPUCount(conf *coreConf, log *zerolog.Logger) { log.Error().Err(err).Msg("error adjusting number of cpus") os.Exit(1) } - //log.Info().Msgf("%s", getVersionString()) + // log.Info().Msgf("%s", getVersionString()) log.Info().Msgf("running on %d cpus", ncpus) } diff --git a/go.mod b/go.mod index 53f5dfd60ea..f430064ebc9 100644 --- a/go.mod +++ b/go.mod @@ -13,7 +13,7 @@ require ( github.com/cheggaaa/pb v1.0.29 github.com/coreos/go-oidc v2.2.1+incompatible github.com/cs3org/cato v0.0.0-20200828125504-e418fc54dd5e - github.com/cs3org/go-cs3apis v0.0.0-20210209091240-d16c30974508 + github.com/cs3org/go-cs3apis v0.0.0-20210310133342-f4a10134033c github.com/dgrijalva/jwt-go v3.2.0+incompatible github.com/eventials/go-tus v0.0.0-20200718001131-45c7ec8f5d59 github.com/ffurano/grpc-proto v0.0.0-20210312134900-65801a1ca184 @@ -35,7 +35,7 @@ require ( github.com/mitchellh/mapstructure v1.4.1 github.com/onsi/ginkgo v1.15.1 github.com/onsi/gomega v1.11.0 - github.com/ory/fosite v0.38.0 + github.com/ory/fosite v0.39.0 github.com/pkg/errors v0.9.1 github.com/pkg/xattr v0.4.3 github.com/pquerna/cachecontrol v0.0.0-20180517163645-1555304b9b35 // indirect @@ -51,12 +51,13 @@ require ( golang.org/x/sys v0.0.0-20210218155724-8ebf48af031b golang.org/x/term v0.0.0-20201117132131-f5c789dd3221 google.golang.org/grpc v1.36.0 + google.golang.org/protobuf v1.23.0 ) go 1.13 -replace github.com/eventials/go-tus => github.com/andrewmostello/go-tus v0.0.0-20200314041820-904a9904af9a - -replace github.com/oleiade/reflections => github.com/oleiade/reflections v1.0.1 - -replace google.golang.org/grpc => google.golang.org/grpc v1.26.0 // temporary downgrade +replace ( + github.com/eventials/go-tus => github.com/andrewmostello/go-tus v0.0.0-20200314041820-904a9904af9a + github.com/oleiade/reflections => github.com/oleiade/reflections v1.0.1 + google.golang.org/grpc => google.golang.org/grpc v1.26.0 // temporary downgrade +) diff --git a/go.sum b/go.sum index 4afb090f4ab..4fec181ab8b 100644 --- a/go.sum +++ b/go.sum @@ -152,6 +152,8 @@ github.com/cs3org/cato v0.0.0-20200828125504-e418fc54dd5e h1:tqSPWQeueWTKnJVMJff github.com/cs3org/cato v0.0.0-20200828125504-e418fc54dd5e/go.mod h1:XJEZ3/EQuI3BXTp/6DUzFr850vlxq11I6satRtz0YQ4= github.com/cs3org/go-cs3apis v0.0.0-20210209091240-d16c30974508 h1:AyeoeZZGPC1lTN7mhgh8HGwwRlvG8hXJ/06q9P+ad9I= github.com/cs3org/go-cs3apis v0.0.0-20210209091240-d16c30974508/go.mod h1:UXha4TguuB52H14EMoSsCqDj7k8a/t7g4gVP+bgY5LY= +github.com/cs3org/go-cs3apis v0.0.0-20210310133342-f4a10134033c h1:+HOawEG8T4uBZI/zJNAFcm4ygbiP+Zci0XRaVGZ0rYM= +github.com/cs3org/go-cs3apis v0.0.0-20210310133342-f4a10134033c/go.mod h1:UXha4TguuB52H14EMoSsCqDj7k8a/t7g4gVP+bgY5LY= github.com/cucumber/godog v0.8.1/go.mod h1:vSh3r/lM+psC1BPXvdkSEuNjmXfpVqrMGYAElF6hxnA= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= @@ -836,6 +838,8 @@ github.com/ory/dockertest/v3 v3.5.4/go.mod h1:J8ZUbNB2FOhm1cFZW9xBpDsODqsSWcyYgt github.com/ory/fosite v0.29.0/go.mod h1:0atSZmXO7CAcs6NPMI/Qtot8tmZYj04Nddoold4S2h0= github.com/ory/fosite v0.38.0 h1:4y+IurqBAu/Gf0NlW47gabRJZyYIqda+OFHMx5fsy6Q= github.com/ory/fosite v0.38.0/go.mod h1:37r59qkOSPueYKmaA7EHiXrDMF1B+XPN+MgkZgTRg3Y= +github.com/ory/fosite v0.39.0 h1:u1Ct/ME7XYzREvufr7ehBIdq/KatjVLIYg/ABqWzprw= +github.com/ory/fosite v0.39.0/go.mod h1:37r59qkOSPueYKmaA7EHiXrDMF1B+XPN+MgkZgTRg3Y= github.com/ory/go-acc v0.0.0-20181118080137-ddc355013f90/go.mod h1:sxnvPCxChFuSmTJGj8FdMupeq1BezCiEpDjTUXQ4hf4= github.com/ory/go-acc v0.2.5 h1:31irXHzG2vnKQSE4weJm7AdfrnpaVjVCq3nD7viXCJE= github.com/ory/go-acc v0.2.5/go.mod h1:4Kb/UnPcT8qRAk3IAxta+hvVapdxTLWtrr7bFLlEgpw= diff --git a/grpc-tests/userprovider_test.go b/grpc-tests/userprovider_test.go index deae3836ec5..979f29c2c9f 100644 --- a/grpc-tests/userprovider_test.go +++ b/grpc-tests/userprovider_test.go @@ -53,7 +53,7 @@ func Test_service_GetUser(t *testing.T) { for _, tt := range providers { t.Run(tt.name, func(t *testing.T) { - //start revad with the specific provider + // start revad with the specific provider cmd := exec.Command("../cmd/revad/revad", "-c", "userproviders/"+tt.name+".toml") err := cmd.Start() @@ -61,15 +61,15 @@ func Test_service_GetUser(t *testing.T) { t.Fatalf("Could not start revad! ERROR: %v", err) } - //wait till port is open + // wait till port is open _ = waitForPort("open") - //even the port is open the service might not be available yet + // even the port is open the service might not be available yet time.Sleep(1 * time.Second) GetUser(t, tt.existingIdp) - //kill revad + // kill revad err = cmd.Process.Signal(os.Kill) if err != nil { t.Fatalf("Could not kill revad! ERROR: %v", err) @@ -184,7 +184,7 @@ func GetUser(t *testing.T, existingIdp string) { if tt.want.User == nil { assert.Nil(t, userResp.User) } else { - //make sure not to run into a nil pointer error + // make sure not to run into a nil pointer error if userResp.User == nil { t.Fatalf("no user in response %v", userResp) } diff --git a/internal/grpc/services/appregistry/appregistry_test.go b/internal/grpc/services/appregistry/appregistry_test.go index 2ad03856e66..3fd817247f9 100644 --- a/internal/grpc/services/appregistry/appregistry_test.go +++ b/internal/grpc/services/appregistry/appregistry_test.go @@ -49,7 +49,7 @@ func Test_ListAppProviders(t *testing.T) { "currently/ignored": "an other address", }, - //only Status and Providers will be asserted in the tests + // only Status and Providers will be asserted in the tests want: ®istrypb.ListAppProvidersResponse{ Status: &rpcv1beta1.Status{ Code: 1, @@ -79,7 +79,7 @@ func Test_ListAppProviders(t *testing.T) { name: "empty rules", rules: map[string]interface{}{}, - //only Status and Providers will be asserted in the tests + // only Status and Providers will be asserted in the tests want: ®istrypb.ListAppProvidersResponse{ Status: &rpcv1beta1.Status{ Code: 1, @@ -97,7 +97,7 @@ func Test_ListAppProviders(t *testing.T) { "text/json": nil, }, - //only Status and Providers will be asserted in the tests + // only Status and Providers will be asserted in the tests want: ®istrypb.ListAppProvidersResponse{ Status: &rpcv1beta1.Status{ Code: 1, @@ -154,7 +154,7 @@ func Test_GetAppProviders(t *testing.T) { { name: "simple", search: &providerv1beta1.ResourceInfo{MimeType: "text/json"}, - //only Status and Providers will be asserted in the tests + // only Status and Providers will be asserted in the tests want: ®istrypb.GetAppProvidersResponse{ Status: &rpcv1beta1.Status{ Code: 1, diff --git a/internal/grpc/services/gateway/ocminvitemanager.go b/internal/grpc/services/gateway/ocminvitemanager.go index 47da1fbcd1c..8d4a6026ceb 100644 --- a/internal/grpc/services/gateway/ocminvitemanager.go +++ b/internal/grpc/services/gateway/ocminvitemanager.go @@ -75,17 +75,33 @@ func (s *svc) AcceptInvite(ctx context.Context, req *invitepb.AcceptInviteReques return res, nil } -func (s *svc) GetRemoteUser(ctx context.Context, req *invitepb.GetRemoteUserRequest) (*invitepb.GetRemoteUserResponse, error) { +func (s *svc) GetAcceptedUser(ctx context.Context, req *invitepb.GetAcceptedUserRequest) (*invitepb.GetAcceptedUserResponse, error) { c, err := pool.GetOCMInviteManagerClient(s.c.OCMInviteManagerEndpoint) if err != nil { - return &invitepb.GetRemoteUserResponse{ + return &invitepb.GetAcceptedUserResponse{ Status: status.NewInternal(ctx, err, "error getting user invite provider client"), }, nil } - res, err := c.GetRemoteUser(ctx, req) + res, err := c.GetAcceptedUser(ctx, req) if err != nil { - return nil, errors.Wrap(err, "gateway: error calling AcceptInvite") + return nil, errors.Wrap(err, "gateway: error calling GetAcceptedUser") + } + + return res, nil +} + +func (s *svc) FindAcceptedUsers(ctx context.Context, req *invitepb.FindAcceptedUsersRequest) (*invitepb.FindAcceptedUsersResponse, error) { + c, err := pool.GetOCMInviteManagerClient(s.c.OCMInviteManagerEndpoint) + if err != nil { + return &invitepb.FindAcceptedUsersResponse{ + Status: status.NewInternal(ctx, err, "error getting user invite provider client"), + }, nil + } + + res, err := c.FindAcceptedUsers(ctx, req) + if err != nil { + return nil, errors.Wrap(err, "gateway: error calling FindAcceptedUsers") } return res, nil diff --git a/internal/grpc/services/gateway/storageprovider.go b/internal/grpc/services/gateway/storageprovider.go index 9bdcbc63d25..38b61eeab29 100644 --- a/internal/grpc/services/gateway/storageprovider.go +++ b/internal/grpc/services/gateway/storageprovider.go @@ -1861,7 +1861,7 @@ func (s *svc) GetQuota(ctx context.Context, req *gateway.GetQuotaRequest) (*prov res, err := c.GetQuota(ctx, &provider.GetQuotaRequest{ Opaque: req.GetOpaque(), - //Ref: req.GetRef(), // TODO send which storage space ... or root + // Ref: req.GetRef(), // TODO send which storage space ... or root }) if err != nil { return nil, errors.Wrap(err, "gateway: error calling GetQuota") diff --git a/internal/grpc/services/ocminvitemanager/ocminvitemanager.go b/internal/grpc/services/ocminvitemanager/ocminvitemanager.go index 072fc55a053..d4ed5acd600 100644 --- a/internal/grpc/services/ocminvitemanager/ocminvitemanager.go +++ b/internal/grpc/services/ocminvitemanager/ocminvitemanager.go @@ -141,16 +141,30 @@ func (s *service) AcceptInvite(ctx context.Context, req *invitepb.AcceptInviteRe }, nil } -func (s *service) GetRemoteUser(ctx context.Context, req *invitepb.GetRemoteUserRequest) (*invitepb.GetRemoteUserResponse, error) { - remoteUser, err := s.im.GetRemoteUser(ctx, req.RemoteUserId) +func (s *service) GetAcceptedUser(ctx context.Context, req *invitepb.GetAcceptedUserRequest) (*invitepb.GetAcceptedUserResponse, error) { + remoteUser, err := s.im.GetAcceptedUser(ctx, req.RemoteUserId) if err != nil { - return &invitepb.GetRemoteUserResponse{ + return &invitepb.GetAcceptedUserResponse{ Status: status.NewInternal(ctx, err, "error fetching remote user details"), }, nil } - return &invitepb.GetRemoteUserResponse{ + return &invitepb.GetAcceptedUserResponse{ Status: status.NewOK(ctx), RemoteUser: remoteUser, }, nil } + +func (s *service) FindAcceptedUsers(ctx context.Context, req *invitepb.FindAcceptedUsersRequest) (*invitepb.FindAcceptedUsersResponse, error) { + acceptedUsers, err := s.im.FindAcceptedUsers(ctx, req.Filter) + if err != nil { + return &invitepb.FindAcceptedUsersResponse{ + Status: status.NewInternal(ctx, err, "error finding remote users"), + }, nil + } + + return &invitepb.FindAcceptedUsersResponse{ + Status: status.NewOK(ctx), + AcceptedUsers: acceptedUsers, + }, nil +} diff --git a/internal/grpc/services/storageprovider/transcoder.go b/internal/grpc/services/storageprovider/transcoder.go index 8ae75329012..4fa6cc52ba0 100644 --- a/internal/grpc/services/storageprovider/transcoder.go +++ b/internal/grpc/services/storageprovider/transcoder.go @@ -30,7 +30,7 @@ func (x XS) String() string { return string(x) } const ( // XSInvalid means the checksum type is invalid. XSInvalid XS = "invalid" - //XSUnset means the checksum is optional. + // XSUnset means the checksum is optional. XSUnset = "unset" // XSAdler32 means the checksum is adler32 XSAdler32 = "adler32" diff --git a/internal/http/services/oidcprovider/oidcprovider.go b/internal/http/services/oidcprovider/oidcprovider.go index 98468e38c53..d4a8b3c7c80 100644 --- a/internal/http/services/oidcprovider/oidcprovider.go +++ b/internal/http/services/oidcprovider/oidcprovider.go @@ -203,7 +203,7 @@ func getStore(clients map[string]fosite.Client) *storage.MemoryStore { Clients: clients, AuthorizeCodes: map[string]storage.StoreAuthorizeCode{}, AccessTokens: map[string]fosite.Requester{}, - RefreshTokens: map[string]fosite.Requester{}, + RefreshTokens: map[string]storage.StoreRefreshToken{}, PKCES: map[string]fosite.Requester{}, AccessTokenRequestIDs: map[string]string{}, RefreshTokenRequestIDs: map[string]string{}, diff --git a/internal/http/services/owncloud/ocdav/propfind.go b/internal/http/services/owncloud/ocdav/propfind.go index 98b815c7a2b..7e880c952a3 100644 --- a/internal/http/services/owncloud/ocdav/propfind.go +++ b/internal/http/services/owncloud/ocdav/propfind.go @@ -53,9 +53,9 @@ const ( // RFC1123 time that mimics oc10. time.RFC1123 would end in "UTC", see https://github.com/golang/go/issues/13781 RFC1123 = "Mon, 02 Jan 2006 15:04:05 GMT" - //_propQuotaUncalculated = "-1" + // _propQuotaUncalculated = "-1" _propQuotaUnknown = "-2" - //_propQuotaUnlimited = "-3" + // _propQuotaUnlimited = "-3" ) // ns is the namespace that is prefixed to the path in the cs3 namespace @@ -184,7 +184,7 @@ func (s *svc) handlePropfind(w http.ResponseWriter, r *http.Request, ns string) // check sub-containers in reverse order and add them to the stack // the reversed order here will produce a more logical sorting of results for i := len(res.Infos) - 1; i >= 0; i-- { - //for i := range res.Infos { + // for i := range res.Infos { if res.Infos[i].Type == provider.ResourceType_RESOURCE_TYPE_CONTAINER { stack = append(stack, res.Infos[i].Path) } @@ -420,10 +420,10 @@ func (s *svc) mdToPropResponse(ctx context.Context, pf *propfindXML, md *provide if ls == nil { propstatOK.Prop = append(propstatOK.Prop, s.newProp("oc:size", size)) } - // A PROPFIND request SHOULD NOT return DAV:quota-available-bytes and DAV:quota-used-bytes + // A PROPFIND request SHOULD NOT return DAV:quota-available-bytes and DAV:quota-used-bytes // from https://www.rfc-editor.org/rfc/rfc4331.html#section-2 - //propstatOK.Prop = append(propstatOK.Prop, s.newProp("d:quota-used-bytes", size)) - //propstatOK.Prop = append(propstatOK.Prop, s.newProp("d:quota-available-bytes", quota)) + // propstatOK.Prop = append(propstatOK.Prop, s.newProp("d:quota-used-bytes", size)) + // propstatOK.Prop = append(propstatOK.Prop, s.newProp("d:quota-available-bytes", quota)) } else { propstatOK.Prop = append(propstatOK.Prop, s.newProp("d:resourcetype", ""), diff --git a/internal/http/services/owncloud/ocdav/report.go b/internal/http/services/owncloud/ocdav/report.go index 3d804a93ca9..5807d5094df 100644 --- a/internal/http/services/owncloud/ocdav/report.go +++ b/internal/http/services/owncloud/ocdav/report.go @@ -29,7 +29,7 @@ import ( func (s *svc) handleReport(w http.ResponseWriter, r *http.Request, ns string) { ctx := r.Context() log := appctx.GetLogger(ctx) - //fn := path.Join(ns, r.URL.Path) + // fn := path.Join(ns, r.URL.Path) rep, status, err := readReport(r.Body) if err != nil { diff --git a/internal/http/services/owncloud/ocdav/trashbin.go b/internal/http/services/owncloud/ocdav/trashbin.go index fd9b9480ce2..e01b54108ec 100644 --- a/internal/http/services/owncloud/ocdav/trashbin.go +++ b/internal/http/services/owncloud/ocdav/trashbin.go @@ -87,7 +87,7 @@ func (h *TrashbinHandler) Handler(s *svc) http.Handler { key, r.URL.Path = router.ShiftPath(r.URL.Path) // TODO another options handler should not be necessary - //if r.Method == http.MethodOptions { + // if r.Method == http.MethodOptions { // s.doOptions(w, r, "trashbin") // return //} diff --git a/internal/http/services/owncloud/ocdav/tus.go b/internal/http/services/owncloud/ocdav/tus.go index 2e250858662..fec279f494b 100644 --- a/internal/http/services/owncloud/ocdav/tus.go +++ b/internal/http/services/owncloud/ocdav/tus.go @@ -60,7 +60,7 @@ func (s *svc) handleTusPost(w http.ResponseWriter, r *http.Request, ns string) { // TODO must be SHA1, ADLER32 or MD5 ... in capital letters???? // curl -X PUT https://demo.owncloud.com/remote.php/webdav/testcs.bin -u demo:demo -d '123' -v -H 'OC-Checksum: SHA1:40bd001563085fc35165329ea1ff5c5ecbdbbeef' - //TODO check Expect: 100-continue + // TODO check Expect: 100-continue // read filename from metadata meta := tusd.ParseMetadataHeader(r.Header.Get("Upload-Metadata")) diff --git a/internal/http/services/owncloud/ocdav/unlock.go b/internal/http/services/owncloud/ocdav/unlock.go index aec38286a6c..3b20189c38a 100644 --- a/internal/http/services/owncloud/ocdav/unlock.go +++ b/internal/http/services/owncloud/ocdav/unlock.go @@ -22,7 +22,7 @@ import ( "net/http" ) -//TODO(jfd): implement unlock +// TODO(jfd): implement unlock func (s *svc) handleUnlock(w http.ResponseWriter, r *http.Request, ns string) { w.WriteHeader(http.StatusNotImplemented) } diff --git a/internal/http/services/owncloud/ocdav/versions.go b/internal/http/services/owncloud/ocdav/versions.go index 61dfe3afc98..37e662136c1 100644 --- a/internal/http/services/owncloud/ocdav/versions.go +++ b/internal/http/services/owncloud/ocdav/versions.go @@ -138,7 +138,7 @@ func (h *VersionsHandler) doListVersions(w http.ResponseWriter, r *http.Request, MimeType: "httpd/unix-directory", Mtime: info.Mtime, Path: "v", - //PermissionSet + // PermissionSet Size: 0, Owner: info.Owner, }) @@ -146,21 +146,21 @@ func (h *VersionsHandler) doListVersions(w http.ResponseWriter, r *http.Request, for i := range versions { vi := &provider.ResourceInfo{ // TODO(jfd) we cannot access version content, this will be a problem when trying to fetch version thumbnails - //Opaque + // Opaque Type: provider.ResourceType_RESOURCE_TYPE_FILE, Id: &provider.ResourceId{ StorageId: "versions", // this is a virtual storage OpaqueId: info.Id.OpaqueId + "@" + versions[i].GetKey(), }, - //Checksum - //Etag: v.ETag, - //MimeType + // Checksum + // Etag: v.ETag, + // MimeType Mtime: &types.Timestamp{ Seconds: versions[i].Mtime, // TODO cs3apis FileVersion should use types.Timestamp instead of uint64 }, Path: path.Join("v", versions[i].Key), - //PermissionSet + // PermissionSet Size: versions[i].Size, Owner: info.Owner, } diff --git a/internal/http/services/owncloud/ocs/conversions/role.go b/internal/http/services/owncloud/ocs/conversions/role.go index b53513a1533..c479df6c384 100644 --- a/internal/http/services/owncloud/ocs/conversions/role.go +++ b/internal/http/services/owncloud/ocs/conversions/role.go @@ -91,7 +91,7 @@ func (r *Role) OCSPermissions() Permissions { // M = Mounted func (r *Role) WebDAVPermissions(isDir, isShared, isMountpoint, isPublic bool) string { var b strings.Builder - //b.Grow(7) + // b.Grow(7) if !isPublic && isShared { fmt.Fprintf(&b, "S") } diff --git a/internal/http/services/owncloud/ocs/handlers/apps/sharing/shares/remote.go b/internal/http/services/owncloud/ocs/handlers/apps/sharing/shares/remote.go index ce685315b78..f77db99cf62 100644 --- a/internal/http/services/owncloud/ocs/handlers/apps/sharing/shares/remote.go +++ b/internal/http/services/owncloud/ocs/handlers/apps/sharing/shares/remote.go @@ -58,7 +58,7 @@ func (h *Handler) createFederatedCloudShare(w http.ResponseWriter, r *http.Reque return } - remoteUserRes, err := c.GetRemoteUser(ctx, &invitepb.GetRemoteUserRequest{ + remoteUserRes, err := c.GetAcceptedUser(ctx, &invitepb.GetAcceptedUserRequest{ RemoteUserId: &userpb.UserId{OpaqueId: shareWithUser, Idp: shareWithProvider}, }) if err != nil { diff --git a/internal/http/services/owncloud/ocs/handlers/cloud/capabilities/uploads.go b/internal/http/services/owncloud/ocs/handlers/cloud/capabilities/uploads.go index a959790e331..9a17cf8e136 100644 --- a/internal/http/services/owncloud/ocs/handlers/cloud/capabilities/uploads.go +++ b/internal/http/services/owncloud/ocs/handlers/cloud/capabilities/uploads.go @@ -56,7 +56,7 @@ func setCapabilitiesForChunkProtocol(cp chunkProtocol, c *data.CapabilitiesData) c.Capabilities.Files.TusSupport = nil case chunkNG: - //2.7+ will use Chunking NG if "capabilities > files > bigfilechunking" is "true" AND "capabilities > dav > chunking" = 1.0 + // 2.7+ will use Chunking NG if "capabilities > files > bigfilechunking" is "true" AND "capabilities > dav > chunking" = 1.0 c.Capabilities.Files.BigFileChunking = true c.Capabilities.Dav.Chunking = "1.0" c.Capabilities.Files.TusSupport = nil diff --git a/internal/http/services/owncloud/ocs/handlers/cloud/users/users.go b/internal/http/services/owncloud/ocs/handlers/cloud/users/users.go index 9922110415e..89538d075ee 100644 --- a/internal/http/services/owncloud/ocs/handlers/cloud/users/users.go +++ b/internal/http/services/owncloud/ocs/handlers/cloud/users/users.go @@ -95,7 +95,7 @@ type Users struct { Email string `json:"email" xml:"email"` DisplayName string `json:"displayname" xml:"displayname"` // FIXME home should never be exposed ... even in oc 10 - //home + // home TwoFactorAuthEnabled bool `json:"two_factor_auth_enabled" xml:"two_factor_auth_enabled"` } diff --git a/internal/http/services/wellknown/openidconfiguration.go b/internal/http/services/wellknown/openidconfiguration.go index 250dd7c3976..eb7da95a6ae 100644 --- a/internal/http/services/wellknown/openidconfiguration.go +++ b/internal/http/services/wellknown/openidconfiguration.go @@ -58,40 +58,40 @@ func (s *svc) doOpenidConfiguration(w http.ResponseWriter, r *http.Request) { // TODO(labkode): do we really need it to validate the token and get user claims? type ProviderMetadata struct { AuthorizationEndpoint string `json:"authorization_endpoint,omitempty"` - //claims_parameter_supported + // claims_parameter_supported ClaimsSupported []string `json:"claims_supported,omitempty"` - //grant_types_supported + // grant_types_supported IDTokenSigningAlgValuesSupported []string `json:"id_token_signing_alg_values_supported,omitempty"` Issuer string `json:"issuer,omitempty"` JwksURI string `json:"jwks_uri,omitempty"` - //registration_endpoint - //request_object_signing_alg_values_supported - //request_parameter_supported - //request_uri_parameter_supported - //require_request_uri_registration - //response_modes_supported + // registration_endpoint + // request_object_signing_alg_values_supported + // request_parameter_supported + // request_uri_parameter_supported + // require_request_uri_registration + // response_modes_supported ResponseTypesSupported []string `json:"response_types_supported,omitempty"` ScopesSupported []string `json:"scopes_supported,omitempty"` SubjectTypesSupported []string `json:"subject_types_supported,omitempty"` TokenEndpoint string `json:"token_endpoint,omitempty"` - //token_endpoint_auth_methods_supported - //token_endpoint_auth_signing_alg_values_supported + // token_endpoint_auth_methods_supported + // token_endpoint_auth_signing_alg_values_supported UserinfoEndpoint string `json:"userinfo_endpoint,omitempty"` - //userinfo_signing_alg_values_supported - //code_challenge_methods_supported + // userinfo_signing_alg_values_supported + // code_challenge_methods_supported IntrospectionEndpoint string `json:"introspection_endpoint,omitempty"` - //introspection_endpoint_auth_methods_supported - //introspection_endpoint_auth_signing_alg_values_supported + // introspection_endpoint_auth_methods_supported + // introspection_endpoint_auth_signing_alg_values_supported RevocationEndpoint string `json:"revocation_endpoint,omitempty"` - //revocation_endpoint_auth_methods_supported - //revocation_endpoint_auth_signing_alg_values_supported - //id_token_encryption_alg_values_supported - //id_token_encryption_enc_values_supported - //userinfo_encryption_alg_values_supported - //userinfo_encryption_enc_values_supported - //request_object_encryption_alg_values_supported - //request_object_encryption_enc_values_supported + // revocation_endpoint_auth_methods_supported + // revocation_endpoint_auth_signing_alg_values_supported + // id_token_encryption_alg_values_supported + // id_token_encryption_enc_values_supported + // userinfo_encryption_alg_values_supported + // userinfo_encryption_enc_values_supported + // request_object_encryption_alg_values_supported + // request_object_encryption_enc_values_supported CheckSessionIframe string `json:"check_session_iframe,omitempty"` EndSessionEndpoint string `json:"end_session_endpoint,omitempty"` - //claim_types_supported + // claim_types_supported } diff --git a/pkg/auth/manager/json/json_test.go b/pkg/auth/manager/json/json_test.go index 194c77c18ad..4e9ee1e50f1 100644 --- a/pkg/auth/manager/json/json_test.go +++ b/pkg/auth/manager/json/json_test.go @@ -132,7 +132,7 @@ func TestGetManagerWithJSONObject(t *testing.T) { assert.EqualError(t, err, tt.expectedError.message) } }) - //cleanup + // cleanup os.Remove(tmpFile.Name()) } } diff --git a/pkg/auth/manager/oidc/oidc.go b/pkg/auth/manager/oidc/oidc.go index b5bea8f9645..9690c548e05 100644 --- a/pkg/auth/manager/oidc/oidc.go +++ b/pkg/auth/manager/oidc/oidc.go @@ -114,10 +114,10 @@ func (am *mgr) Authenticate(ctx context.Context, clientID, clientSecret string) } log.Debug().Interface("claims", claims).Interface("userInfo", userInfo).Msg("unmarshalled userinfo") - if claims["issuer"] == nil { //This is not set in simplesamlphp + if claims["issuer"] == nil { // This is not set in simplesamlphp claims["issuer"] = am.c.Issuer } - if claims["email_verified"] == nil { //This is not set in simplesamlphp + if claims["email_verified"] == nil { // This is not set in simplesamlphp claims["email_verified"] = false } diff --git a/pkg/eosclient/eosgrpc/eos_grpc/eos_grpc.proto b/pkg/eosclient/eosgrpc/eos_grpc/eos_grpc.proto index 9b67948db2a..dc800cc4907 100644 --- a/pkg/eosclient/eosgrpc/eos_grpc/eos_grpc.proto +++ b/pkg/eosclient/eosgrpc/eos_grpc/eos_grpc.proto @@ -511,7 +511,7 @@ message ManilaRequest { } message ManilaResponse { - string msg = 1; //for generic messages + string msg = 1; // for generic messages int32 code = 2; // < 1 is an error -- > 1 is OK int64 total_used = 3; int64 total_capacity = 4; diff --git a/pkg/eosclient/eosgrpc/eosgrpc.go b/pkg/eosclient/eosgrpc/eosgrpc.go index 56405e7c27b..e8ab2a43a03 100644 --- a/pkg/eosclient/eosgrpc/eosgrpc.go +++ b/pkg/eosclient/eosgrpc/eosgrpc.go @@ -616,7 +616,7 @@ func (c *Client) GetFileInfoByPath(ctx context.Context, uid, gid, path string) ( // - "File not found is not an error", it's a legitimate result of a legitimate check // - Assuming that any error means file not found is doubly poisonous return nil, errtypes.NotFound(err.Error()) - //return nil, nil + // return nil, nil } if rsp == nil { diff --git a/pkg/logger/logger.go b/pkg/logger/logger.go index ae861d0bd0d..7c35a7ecd29 100644 --- a/pkg/logger/logger.go +++ b/pkg/logger/logger.go @@ -35,7 +35,7 @@ func init() { type Mode string const ( - //JSONMode outputs JSON. + // JSONMode outputs JSON. JSONMode Mode = "json" // ConsoleMode outputs human-readable logs. ConsoleMode Mode = "console" diff --git a/pkg/ocm/invite/invite.go b/pkg/ocm/invite/invite.go index 9c11b248e5f..c771551c83f 100644 --- a/pkg/ocm/invite/invite.go +++ b/pkg/ocm/invite/invite.go @@ -37,6 +37,9 @@ type Manager interface { // AcceptInvite completes an invitation acceptance. AcceptInvite(ctx context.Context, invite *invitepb.InviteToken, remoteUser *userpb.User) error - // GetRemoteUser retrieves details about a remote user who has accepted an invite to share. - GetRemoteUser(ctx context.Context, remoteUserID *userpb.UserId) (*userpb.User, error) + // GetAcceptedUser retrieves details about a remote user who has accepted an invite to share. + GetAcceptedUser(ctx context.Context, remoteUserID *userpb.UserId) (*userpb.User, error) + + // FindAcceptedUsers finds remote users who have accepted invites based on their attributes. + FindAcceptedUsers(ctx context.Context, query string) ([]*userpb.User, error) } diff --git a/pkg/ocm/invite/manager/json/json.go b/pkg/ocm/invite/manager/json/json.go index 49fc0880b8c..303863c4028 100644 --- a/pkg/ocm/invite/manager/json/json.go +++ b/pkg/ocm/invite/manager/json/json.go @@ -273,7 +273,7 @@ func (m *manager) AcceptInvite(ctx context.Context, invite *invitepb.InviteToken return nil } -func (m *manager) GetRemoteUser(ctx context.Context, remoteUserID *userpb.UserId) (*userpb.User, error) { +func (m *manager) GetAcceptedUser(ctx context.Context, remoteUserID *userpb.UserId) (*userpb.User, error) { userKey := user.ContextMustGetUser(ctx).GetId().GetOpaqueId() for _, acceptedUser := range m.model.AcceptedUsers[userKey] { @@ -284,6 +284,23 @@ func (m *manager) GetRemoteUser(ctx context.Context, remoteUserID *userpb.UserId return nil, errtypes.NotFound(remoteUserID.OpaqueId) } +func (m *manager) FindAcceptedUsers(ctx context.Context, query string) ([]*userpb.User, error) { + users := []*userpb.User{} + userKey := user.ContextMustGetUser(ctx).GetId().GetOpaqueId() + for _, acceptedUser := range m.model.AcceptedUsers[userKey] { + if query == "" || userContains(acceptedUser, query) { + users = append(users, acceptedUser) + } + } + return users, nil +} + +func userContains(u *userpb.User, query string) bool { + query = strings.ToLower(query) + return strings.Contains(strings.ToLower(u.Username), query) || strings.Contains(strings.ToLower(u.DisplayName), query) || + strings.Contains(strings.ToLower(u.Mail), query) || strings.Contains(strings.ToLower(u.Id.OpaqueId), query) +} + func (m *manager) getTokenIfValid(token *invitepb.InviteToken) (*invitepb.InviteToken, error) { inviteToken, ok := m.model.Invites[token.GetToken()] if !ok { diff --git a/pkg/ocm/invite/manager/memory/memory.go b/pkg/ocm/invite/manager/memory/memory.go index 9a0350b35e0..4e0f68388d8 100644 --- a/pkg/ocm/invite/manager/memory/memory.go +++ b/pkg/ocm/invite/manager/memory/memory.go @@ -171,8 +171,7 @@ func (m *manager) AcceptInvite(ctx context.Context, invite *invitepb.InviteToken return nil } -func (m *manager) GetRemoteUser(ctx context.Context, remoteUserID *userpb.UserId) (*userpb.User, error) { - +func (m *manager) GetAcceptedUser(ctx context.Context, remoteUserID *userpb.UserId) (*userpb.User, error) { currUser := user.ContextMustGetUser(ctx).GetId().GetOpaqueId() usersList, ok := m.AcceptedUsers.Load(currUser) if !ok { @@ -186,7 +185,29 @@ func (m *manager) GetRemoteUser(ctx context.Context, remoteUserID *userpb.UserId } } return nil, errtypes.NotFound(remoteUserID.OpaqueId) +} + +func (m *manager) FindAcceptedUsers(ctx context.Context, query string) ([]*userpb.User, error) { + currUser := user.ContextMustGetUser(ctx).GetId().GetOpaqueId() + usersList, ok := m.AcceptedUsers.Load(currUser) + if !ok { + return []*userpb.User{}, nil + } + + users := []*userpb.User{} + acceptedUsers := usersList.([]*userpb.User) + for _, acceptedUser := range acceptedUsers { + if query == "" || userContains(acceptedUser, query) { + users = append(users, acceptedUser) + } + } + return users, nil +} +func userContains(u *userpb.User, query string) bool { + query = strings.ToLower(query) + return strings.Contains(strings.ToLower(u.Username), query) || strings.Contains(strings.ToLower(u.DisplayName), query) || + strings.Contains(strings.ToLower(u.Mail), query) || strings.Contains(strings.ToLower(u.Id.OpaqueId), query) } func (m *manager) getTokenIfValid(token *invitepb.InviteToken) (*invitepb.InviteToken, error) { diff --git a/pkg/ocm/share/manager/json/json.go b/pkg/ocm/share/manager/json/json.go index 2f16661e88b..850dc712a72 100644 --- a/pkg/ocm/share/manager/json/json.go +++ b/pkg/ocm/share/manager/json/json.go @@ -109,8 +109,11 @@ func loadOrCreate(file string) (*shareModel, error) { return nil, err } - if m.State == nil { - m.State = map[string]map[string]ocm.ShareState{} + if m.Shares == nil { + m.Shares = map[string]interface{}{} + } + if m.ReceivedShares == nil { + m.ReceivedShares = map[string]interface{}{} } m.file = file @@ -119,9 +122,8 @@ func loadOrCreate(file string) (*shareModel, error) { type shareModel struct { file string - State map[string]map[string]ocm.ShareState `json:"state"` // map[username]map[share_id]boolean - Shares []*ocm.Share `json:"shares"` - ReceivedShares []*ocm.Share `json:"received_shares"` + Shares map[string]interface{} `json:"shares"` + ReceivedShares map[string]interface{} `json:"received_shares"` } type config struct { @@ -331,10 +333,22 @@ func (m *mgr) Share(ctx context.Context, md *provider.ResourceId, g *ocm.ShareGr err = errors.Wrap(err, "error reading model") return nil, err } + if isOwnersMeshProvider { - m.model.Shares = append(m.model.Shares, s) + encShare, err := utils.MarshalProtoV1ToJSON(s) + if err != nil { + return nil, err + } + m.model.Shares[s.Id.OpaqueId] = string(encShare) } else { - m.model.ReceivedShares = append(m.model.ReceivedShares, s) + encShare, err := utils.MarshalProtoV1ToJSON(&ocm.ReceivedShare{ + Share: s, + State: ocm.ShareState_SHARE_STATE_PENDING, + }) + if err != nil { + return nil, err + } + m.model.ReceivedShares[s.Id.OpaqueId] = string(encShare) } if err := m.model.Save(); err != nil { @@ -355,11 +369,14 @@ func (m *mgr) getByID(ctx context.Context, id *ocm.ShareId) (*ocm.Share, error) return nil, err } - for _, s := range m.model.Shares { - if s.GetId().OpaqueId == id.OpaqueId { - return s, nil + if s, ok := m.model.Shares[id.OpaqueId]; ok { + var share ocm.Share + if err := utils.UnmarshalJSONToProtoV1([]byte(s.(string)), &share); err != nil { + return nil, err } + return &share, nil } + return nil, errtypes.NotFound(id.String()) } @@ -373,9 +390,13 @@ func (m *mgr) getByKey(ctx context.Context, key *ocm.ShareKey) (*ocm.Share, erro } for _, s := range m.model.Shares { - if (utils.UserEqual(key.Owner, s.Owner) || utils.UserEqual(key.Owner, s.Creator)) && - utils.ResourceEqual(key.ResourceId, s.ResourceId) && utils.GranteeEqual(key.Grantee, s.Grantee) { - return s, nil + var share ocm.Share + if err := utils.UnmarshalJSONToProtoV1([]byte(s.(string)), &share); err != nil { + continue + } + if (utils.UserEqual(key.Owner, share.Owner) || utils.UserEqual(key.Owner, share.Creator)) && + utils.ResourceEqual(key.ResourceId, share.ResourceId) && utils.GranteeEqual(key.Grantee, share.Grantee) { + return &share, nil } } return nil, errtypes.NotFound(key.String()) @@ -424,11 +445,14 @@ func (m *mgr) Unshare(ctx context.Context, ref *ocm.ShareReference) error { } user := user.ContextMustGetUser(ctx) - for i, s := range m.model.Shares { - if sharesEqual(ref, s) { - if utils.UserEqual(user.Id, s.Owner) || utils.UserEqual(user.Id, s.Creator) { - m.model.Shares[len(m.model.Shares)-1], m.model.Shares[i] = m.model.Shares[i], m.model.Shares[len(m.model.Shares)-1] - m.model.Shares = m.model.Shares[:len(m.model.Shares)-1] + for id, s := range m.model.Shares { + var share ocm.Share + if err := utils.UnmarshalJSONToProtoV1([]byte(s.(string)), &share); err != nil { + continue + } + if sharesEqual(ref, &share) { + if utils.UserEqual(user.Id, share.Owner) || utils.UserEqual(user.Id, share.Creator) { + delete(m.model.Shares, id) if err := m.model.Save(); err != nil { err = errors.Wrap(err, "error saving model") return err @@ -464,20 +488,29 @@ func (m *mgr) UpdateShare(ctx context.Context, ref *ocm.ShareReference, p *ocm.S } user := user.ContextMustGetUser(ctx) - for i, s := range m.model.Shares { - if sharesEqual(ref, s) { - if utils.UserEqual(user.Id, s.Owner) || utils.UserEqual(user.Id, s.Creator) { + for id, s := range m.model.Shares { + var share ocm.Share + if err := utils.UnmarshalJSONToProtoV1([]byte(s.(string)), &share); err != nil { + continue + } + if sharesEqual(ref, &share) { + if utils.UserEqual(user.Id, share.Owner) || utils.UserEqual(user.Id, share.Creator) { now := time.Now().UnixNano() - m.model.Shares[i].Permissions = p - m.model.Shares[i].Mtime = &typespb.Timestamp{ + share.Permissions = p + share.Mtime = &typespb.Timestamp{ Seconds: uint64(now / 1000000000), Nanos: uint32(now % 1000000000), } + encShare, err := utils.MarshalProtoV1ToJSON(&share) + if err != nil { + return nil, err + } + m.model.Shares[id] = string(encShare) if err := m.model.Save(); err != nil { err = errors.Wrap(err, "error saving model") return nil, err } - return m.model.Shares[i], nil + return &share, nil } } } @@ -496,17 +529,21 @@ func (m *mgr) ListShares(ctx context.Context, filters []*ocm.ListOCMSharesReques user := user.ContextMustGetUser(ctx) for _, s := range m.model.Shares { - if utils.UserEqual(user.Id, s.Owner) || utils.UserEqual(user.Id, s.Creator) { + var share ocm.Share + if err := utils.UnmarshalJSONToProtoV1([]byte(s.(string)), &share); err != nil { + continue + } + if utils.UserEqual(user.Id, share.Owner) || utils.UserEqual(user.Id, share.Creator) { // no filter we return earlier if len(filters) == 0 { - ss = append(ss, s) + ss = append(ss, &share) } else { // check filters // TODO(labkode): add the rest of filters. for _, f := range filters { if f.Type == ocm.ListOCMSharesRequest_Filter_TYPE_RESOURCE_ID { - if s.ResourceId.StorageId == f.GetResourceId().StorageId && s.ResourceId.OpaqueId == f.GetResourceId().OpaqueId { - ss = append(ss, s) + if share.ResourceId.StorageId == f.GetResourceId().StorageId && share.ResourceId.OpaqueId == f.GetResourceId().OpaqueId { + ss = append(ss, &share) } } } @@ -528,19 +565,22 @@ func (m *mgr) ListReceivedShares(ctx context.Context) ([]*ocm.ReceivedShare, err user := user.ContextMustGetUser(ctx) for _, s := range m.model.ReceivedShares { - if utils.UserEqual(user.Id, s.Owner) || utils.UserEqual(user.Id, s.Creator) { + var rs ocm.ReceivedShare + if err := utils.UnmarshalJSONToProtoV1([]byte(s.(string)), &rs); err != nil { + continue + } + share := rs.Share + if utils.UserEqual(user.Id, share.Owner) || utils.UserEqual(user.Id, share.Creator) { // omit shares created by me continue } - if s.Grantee.Type == provider.GranteeType_GRANTEE_TYPE_USER && utils.UserEqual(user.Id, s.Grantee.GetUserId()) { - rs := m.convert(ctx, s) - rss = append(rss, rs) - } else if s.Grantee.Type == provider.GranteeType_GRANTEE_TYPE_GROUP { + if share.Grantee.Type == provider.GranteeType_GRANTEE_TYPE_USER && utils.UserEqual(user.Id, share.Grantee.GetUserId()) { + rss = append(rss, &rs) + } else if share.Grantee.Type == provider.GranteeType_GRANTEE_TYPE_GROUP { // check if all user groups match this share; TODO(labkode): filter shares created by us. for _, g := range user.Groups { - if g == s.Grantee.GetGroupId().OpaqueId { - rs := m.convert(ctx, s) - rss = append(rss, rs) + if g == share.Grantee.GetGroupId().OpaqueId { + rss = append(rss, &rs) break } } @@ -549,21 +589,6 @@ func (m *mgr) ListReceivedShares(ctx context.Context) ([]*ocm.ReceivedShare, err return rss, nil } -// convert must be called in a lock-controlled block. -func (m *mgr) convert(ctx context.Context, s *ocm.Share) *ocm.ReceivedShare { - rs := &ocm.ReceivedShare{ - Share: s, - State: ocm.ShareState_SHARE_STATE_PENDING, - } - user := user.ContextMustGetUser(ctx) - if v, ok := m.model.State[user.Id.String()]; ok { - if state, ok := v[s.Id.String()]; ok { - rs.State = state - } - } - return rs -} - func (m *mgr) GetReceivedShare(ctx context.Context, ref *ocm.ShareReference) (*ocm.ReceivedShare, error) { return m.getReceived(ctx, ref) } @@ -579,15 +604,18 @@ func (m *mgr) getReceived(ctx context.Context, ref *ocm.ShareReference) (*ocm.Re user := user.ContextMustGetUser(ctx) for _, s := range m.model.ReceivedShares { - if sharesEqual(ref, s) { - if s.Grantee.Type == provider.GranteeType_GRANTEE_TYPE_USER && utils.UserEqual(user.Id, s.Grantee.GetUserId()) { - rs := m.convert(ctx, s) - return rs, nil - } else if s.Grantee.Type == provider.GranteeType_GRANTEE_TYPE_GROUP { + var rs ocm.ReceivedShare + if err := utils.UnmarshalJSONToProtoV1([]byte(s.(string)), &rs); err != nil { + continue + } + share := rs.Share + if sharesEqual(ref, share) { + if share.Grantee.Type == provider.GranteeType_GRANTEE_TYPE_USER && utils.UserEqual(user.Id, share.Grantee.GetUserId()) { + return &rs, nil + } else if share.Grantee.Type == provider.GranteeType_GRANTEE_TYPE_GROUP { for _, g := range user.Groups { - if s.Grantee.GetGroupId().OpaqueId == g { - rs := m.convert(ctx, s) - return rs, nil + if share.Grantee.GetGroupId().OpaqueId == g { + return &rs, nil } } } @@ -602,7 +630,6 @@ func (m *mgr) UpdateReceivedShare(ctx context.Context, ref *ocm.ShareReference, return nil, err } - user := user.ContextMustGetUser(ctx) m.Lock() defer m.Unlock() @@ -611,15 +638,12 @@ func (m *mgr) UpdateReceivedShare(ctx context.Context, ref *ocm.ShareReference, return nil, err } - if v, ok := m.model.State[user.Id.String()]; ok { - v[rs.Share.Id.String()] = f.GetState() - m.model.State[user.Id.String()] = v - } else { - a := map[string]ocm.ShareState{ - rs.Share.Id.String(): f.GetState(), - } - m.model.State[user.Id.String()] = a + rs.State = f.GetState() + encShare, err := utils.MarshalProtoV1ToJSON(rs) + if err != nil { + return nil, err } + m.model.ReceivedShares[rs.Share.Id.GetOpaqueId()] = string(encShare) if err := m.model.Save(); err != nil { err = errors.Wrap(err, "error saving model") diff --git a/pkg/publicshare/manager/json/json.go b/pkg/publicshare/manager/json/json.go index 512f510fc9a..a07728addca 100644 --- a/pkg/publicshare/manager/json/json.go +++ b/pkg/publicshare/manager/json/json.go @@ -19,7 +19,6 @@ package json import ( - "bytes" "context" "encoding/json" "fmt" @@ -43,7 +42,6 @@ import ( "github.com/cs3org/reva/pkg/publicshare" "github.com/cs3org/reva/pkg/publicshare/manager/registry" "github.com/cs3org/reva/pkg/utils" - "github.com/golang/protobuf/jsonpb" "github.com/mitchellh/mapstructure" "github.com/pkg/errors" "go.opencensus.io/trace" @@ -64,8 +62,6 @@ func New(c map[string]interface{}) (publicshare.Manager, error) { m := manager{ mutex: &sync.Mutex{}, - marshaler: jsonpb.Marshaler{}, - unmarshaler: jsonpb.Unmarshaler{}, file: conf.File, passwordHashCost: conf.SharePasswordHashCost, janitorRunInterval: conf.JanitorRunInterval, @@ -120,8 +116,6 @@ type manager struct { mutex *sync.Mutex file string - marshaler jsonpb.Marshaler - unmarshaler jsonpb.Unmarshaler passwordHashCost int janitorRunInterval int enableExpiredSharesCleanup bool @@ -198,8 +192,8 @@ func (m *manager) CreatePublicShare(ctx context.Context, u *user.User, rInfo *pr m.mutex.Lock() defer m.mutex.Unlock() - encShare := bytes.Buffer{} - if err := m.marshaler.Marshal(&encShare, &ps.PublicShare); err != nil { + encShare, err := utils.MarshalProtoV1ToJSON(&ps.PublicShare) + if err != nil { return nil, err } @@ -210,7 +204,7 @@ func (m *manager) CreatePublicShare(ctx context.Context, u *user.User, rInfo *pr if _, ok := db[s.Id.GetOpaqueId()]; !ok { db[s.Id.GetOpaqueId()] = map[string]interface{}{ - "share": encShare.String(), + "share": string(encShare), "password": ps.Password, } } else { @@ -281,8 +275,8 @@ func (m *manager) UpdatePublicShare(ctx context.Context, u *user.User, req *link return nil, err } - buff := bytes.Buffer{} - if err := m.marshaler.Marshal(&buff, share); err != nil { + encShare, err := utils.MarshalProtoV1ToJSON(share) + if err != nil { return nil, err } @@ -294,7 +288,7 @@ func (m *manager) UpdatePublicShare(ctx context.Context, u *user.User, req *link if ok && passwordChanged { data["password"] = newPasswordEncoded } - data["share"] = buff.String() + data["share"] = string(encShare) db[share.Id.OpaqueId] = data @@ -327,20 +321,19 @@ func (m *manager) GetPublicShare(ctx context.Context, u *user.User, ref *link.Pu for _, v := range db { d := v.(map[string]interface{})["share"] - ps := &link.PublicShare{} - r := bytes.NewBuffer([]byte(d.(string))) - if err := m.unmarshaler.Unmarshal(r, ps); err != nil { + var ps link.PublicShare + if err := utils.UnmarshalJSONToProtoV1([]byte(d.(string)), &ps); err != nil { return nil, err } if ref.GetId().GetOpaqueId() == ps.Id.OpaqueId { - if !notExpired(ps) { - if err := m.revokeExpiredPublicShare(ctx, ps, u); err != nil { + if !notExpired(&ps) { + if err := m.revokeExpiredPublicShare(ctx, &ps, u); err != nil { return nil, err } return nil, errors.New("no shares found by id:" + ref.GetId().String()) } - return ps, nil + return &ps, nil } } @@ -360,9 +353,8 @@ func (m *manager) ListPublicShares(ctx context.Context, u *user.User, filters [] } for _, v := range db { - r := bytes.NewBuffer([]byte(v.(map[string]interface{})["share"].(string))) - local := &publicShare{} - if err := m.unmarshaler.Unmarshal(r, &local.PublicShare); err != nil { + var local publicShare + if err := utils.UnmarshalJSONToProtoV1([]byte(v.(map[string]interface{})["share"].(string)), &local.PublicShare); err != nil { return nil, err } @@ -410,12 +402,11 @@ func (m *manager) cleanupExpiredShares() { for _, v := range db { d := v.(map[string]interface{})["share"] - ps := &link.PublicShare{} - r := bytes.NewBuffer([]byte(d.(string))) - _ = m.unmarshaler.Unmarshal(r, ps) + var ps link.PublicShare + _ = utils.UnmarshalJSONToProtoV1([]byte(d.(string)), &ps) - if !notExpired(ps) { - _ = m.revokeExpiredPublicShare(context.Background(), ps, nil) + if !notExpired(&ps) { + _ = m.revokeExpiredPublicShare(context.Background(), &ps, nil) } } } @@ -490,14 +481,13 @@ func (m *manager) getByToken(ctx context.Context, token string) (*link.PublicSha defer m.mutex.Unlock() for _, v := range db { - r := bytes.NewBuffer([]byte(v.(map[string]interface{})["share"].(string))) - local := &link.PublicShare{} - if err := m.unmarshaler.Unmarshal(r, local); err != nil { + var local link.PublicShare + if err := utils.UnmarshalJSONToProtoV1([]byte(v.(map[string]interface{})["share"].(string)), &local); err != nil { return nil, err } if local.Token == token { - return local, nil + return &local, nil } } @@ -515,17 +505,16 @@ func (m *manager) GetPublicShareByToken(ctx context.Context, token, password str defer m.mutex.Unlock() for _, v := range db { - r := bytes.NewBuffer([]byte(v.(map[string]interface{})["share"].(string))) passDB := v.(map[string]interface{})["password"].(string) - local := &link.PublicShare{} - if err := m.unmarshaler.Unmarshal(r, local); err != nil { + var local link.PublicShare + if err := utils.UnmarshalJSONToProtoV1([]byte(v.(map[string]interface{})["share"].(string)), &local); err != nil { return nil, err } if local.Token == token { - if !notExpired(local) { + if !notExpired(&local) { // TODO user is not needed at all in this API. - if err := m.revokeExpiredPublicShare(ctx, local, nil); err != nil { + if err := m.revokeExpiredPublicShare(ctx, &local, nil); err != nil { return nil, err } break @@ -533,12 +522,12 @@ func (m *manager) GetPublicShareByToken(ctx context.Context, token, password str if local.PasswordProtected { if err := bcrypt.CompareHashAndPassword([]byte(passDB), []byte(password)); err == nil { - return local, nil + return &local, nil } return nil, errtypes.InvalidCredentials("json: invalid password") } - return local, nil + return &local, nil } } diff --git a/pkg/share/manager/json/json.go b/pkg/share/manager/json/json.go index b146428c2ed..48f52d6c145 100644 --- a/pkg/share/manager/json/json.go +++ b/pkg/share/manager/json/json.go @@ -119,7 +119,7 @@ func loadOrCreate(file string) (*shareModel, error) { type shareModel struct { file string - State map[string]map[string]collaboration.ShareState `json:"state"` // map[username]map[share_id]boolean + State map[string]map[string]collaboration.ShareState `json:"state"` // map[username]map[share_id]ShareState Shares []*collaboration.Share `json:"shares"` Grantees []interface{} `json:"grantees"` } diff --git a/pkg/storage/fs/owncloud/owncloud.go b/pkg/storage/fs/owncloud/owncloud.go index 19efc2f8a5e..a7a0f471527 100644 --- a/pkg/storage/fs/owncloud/owncloud.go +++ b/pkg/storage/fs/owncloud/owncloud.go @@ -72,7 +72,7 @@ const ( mdPrefix string = ocPrefix + "md." // arbitrary metadata favPrefix string = ocPrefix + "fav." // favorite flag, per user etagPrefix string = ocPrefix + "etag." // allow overriding a calculated etag with one from the extended attributes - //checksumPrefix string = ocPrefix + "cs." // TODO add checksum support + // checksumPrefix string = ocPrefix + "cs." // TODO add checksum support ) @@ -695,7 +695,7 @@ func readOrCreateID(ctx context.Context, ip string, conn redis.Conn) string { log := appctx.GetLogger(ctx) // read extended file attribute for id - //generate if not present + // generate if not present var id []byte var err error if id, err = xattr.Get(ip, idAttribute); err != nil { diff --git a/pkg/storage/fs/s3/s3.go b/pkg/storage/fs/s3/s3.go index 7e4f1011756..841d78a398e 100644 --- a/pkg/storage/fs/s3/s3.go +++ b/pkg/storage/fs/s3/s3.go @@ -504,7 +504,7 @@ func (fs *s3FS) GetMD(ctx context.Context, ref *provider.Reference, mdKeys []str log.Debug(). Str("fn", fn). Msg("trying to list prefix") - //try by listing parent to find directory + // try by listing parent to find directory input := &s3.ListObjectsV2Input{ Bucket: aws.String(fs.config.Bucket), Prefix: aws.String(fn), diff --git a/pkg/storage/migrate/metadata.go b/pkg/storage/migrate/metadata.go index 571b16cd6b6..b9aae4b3abf 100644 --- a/pkg/storage/migrate/metadata.go +++ b/pkg/storage/migrate/metadata.go @@ -42,16 +42,16 @@ type metaData struct { MTime int `json:"mtime"` } -//ImportMetadata from a files.jsonl file in exportPath. The files must already be present on the storage -//Will set etag and mtime +// ImportMetadata from a files.jsonl file in exportPath. The files must already be present on the storage +// Will set etag and mtime func ImportMetadata(ctx context.Context, client gateway.GatewayAPIClient, exportPath string, ns string) error { filesJSONL, err := os.Open(path.Join(exportPath, "files.jsonl")) if err != nil { return err } - defer filesJSONL.Close() jsonLines := bufio.NewScanner(filesJSONL) + filesJSONL.Close() for jsonLines.Scan() { var fileData metaData @@ -68,7 +68,7 @@ func ImportMetadata(ctx context.Context, client gateway.GatewayAPIClient, export if fileData.MTime != 0 { m["mtime"] = strconv.Itoa(fileData.MTime) } - //TODO permissions? is done via share? but this is owner permissions + // TODO permissions? is done via share? but this is owner permissions if len(m) > 0 { resourcePath := path.Join(ns, path.Base(exportPath), strings.TrimPrefix(fileData.Path, "/files/")) diff --git a/pkg/storage/migrate/shares.go b/pkg/storage/migrate/shares.go index 8bd1943dc61..4fc746d0845 100644 --- a/pkg/storage/migrate/shares.go +++ b/pkg/storage/migrate/shares.go @@ -48,15 +48,15 @@ type share struct { Token string `json:"token"` } -//ImportShares from a shares.jsonl file in exportPath. The files must already be present on the storage +// ImportShares from a shares.jsonl file in exportPath. The files must already be present on the storage func ImportShares(ctx context.Context, client gateway.GatewayAPIClient, exportPath string, ns string) error { sharesJSONL, err := os.Open(path.Join(exportPath, "shares.jsonl")) if err != nil { return err } - defer sharesJSONL.Close() jsonLines := bufio.NewScanner(sharesJSONL) + sharesJSONL.Close() for jsonLines.Scan() { var shareData share @@ -65,7 +65,7 @@ func ImportShares(ctx context.Context, client gateway.GatewayAPIClient, exportPa return err } - //Stat file, skip share creation if it does not exist on the target system + // Stat file, skip share creation if it does not exist on the target system resourcePath := path.Join(ns, path.Base(exportPath), shareData.Path) statReq := &provider.StatRequest{ Ref: &provider.Reference{ diff --git a/pkg/storage/utils/ace/ace.go b/pkg/storage/utils/ace/ace.go index 1057abb0827..7408e5e4979 100644 --- a/pkg/storage/utils/ace/ace.go +++ b/pkg/storage/utils/ace/ace.go @@ -110,7 +110,7 @@ import ( // 0x00 = key value // 0x01 = v1 ... type ACE struct { - //NFSv4 acls + // NFSv4 acls _type string // t flags string // f principal string // im key @@ -220,21 +220,21 @@ func (e *ACE) grantPermissionSet() *provider.ResourcePermissions { p.Move = true } } - //a + // a if strings.Contains(e.permissions, "a") { // TODO append data to file permission? p.CreateContainer = true } - //x - //if strings.Contains(e.Permissions, "x") { + // x + // if strings.Contains(e.Permissions, "x") { // TODO execute file permission? // TODO change directory permission? - //} - //d + // } + // d if strings.Contains(e.permissions, "d") { p.Delete = true } - //D ? + // D ? // sharing if strings.Contains(e.permissions, "C") { diff --git a/pkg/storage/utils/acl/acl.go b/pkg/storage/utils/acl/acl.go index a8f33273319..a24c6fa17a1 100644 --- a/pkg/storage/utils/acl/acl.go +++ b/pkg/storage/utils/acl/acl.go @@ -60,9 +60,9 @@ func Parse(acls string, delimiter string) (*ACLs, error) { return nil, err } // for now we ignore default / empty qualifiers - //if entry.Qualifier == "" { + // if entry.Qualifier == "" { // continue - //} + // } entries = append(entries, entry) } diff --git a/pkg/storage/utils/chunking/chunking.go b/pkg/storage/utils/chunking/chunking.go index e9121693052..5130d88772b 100644 --- a/pkg/storage/utils/chunking/chunking.go +++ b/pkg/storage/utils/chunking/chunking.go @@ -130,7 +130,7 @@ func (c *ChunkHandler) saveChunk(path string, r io.ReadCloser) (bool, string, er if err != nil { return false, "", err } - //c.logger.Info().Log("chunkfolder", chunksFolderName) + // c.logger.Info().Log("chunkfolder", chunksFolderName) chunkTarget := chunksFolderName + "/" + fmt.Sprintf("%d", chunkInfo.CurrentChunk) if err = os.Rename(chunkTempFilename, chunkTarget); err != nil { diff --git a/pkg/storage/utils/decomposedfs/decomposedfs.go b/pkg/storage/utils/decomposedfs/decomposedfs.go index 05c5d021634..abe5cfd1c74 100644 --- a/pkg/storage/utils/decomposedfs/decomposedfs.go +++ b/pkg/storage/utils/decomposedfs/decomposedfs.go @@ -18,8 +18,8 @@ package decomposedfs -//go:generate mockery -name PermissionsChecker -//go:generate mockery -name Tree +// go:generate mockery -name PermissionsChecker +// go:generate mockery -name Tree import ( "context" @@ -58,9 +58,9 @@ type Tree interface { GetMD(ctx context.Context, node *node.Node) (os.FileInfo, error) ListFolder(ctx context.Context, node *node.Node) ([]*node.Node, error) - //CreateHome(owner *userpb.UserId) (n *node.Node, err error) + // CreateHome(owner *userpb.UserId) (n *node.Node, err error) CreateDir(ctx context.Context, node *node.Node) (err error) - //CreateReference(ctx context.Context, node *node.Node, targetURI *url.URL) error + // CreateReference(ctx context.Context, node *node.Node, targetURI *url.URL) error Move(ctx context.Context, oldNode *node.Node, newNode *node.Node) (err error) Delete(ctx context.Context, node *node.Node) (err error) RestoreRecycleItemFunc(ctx context.Context, key string) (*node.Node, func() error, error) diff --git a/pkg/storage/utils/decomposedfs/decomposedfs_concurrency_test.go b/pkg/storage/utils/decomposedfs/decomposedfs_concurrency_test.go index 0d00d888d11..02bcf021759 100644 --- a/pkg/storage/utils/decomposedfs/decomposedfs_concurrency_test.go +++ b/pkg/storage/utils/decomposedfs/decomposedfs_concurrency_test.go @@ -102,7 +102,7 @@ var _ = Describe("Decomposed", func() { }) PIt("generates two revisions", func() { - //runtime.GOMAXPROCS(1) // uncomment to remove concurrency and see revisions working. + // runtime.GOMAXPROCS(1) // uncomment to remove concurrency and see revisions working. wg := &sync.WaitGroup{} wg.Add(2) diff --git a/pkg/storage/utils/decomposedfs/tree/tree.go b/pkg/storage/utils/decomposedfs/tree/tree.go index f6517feaf7e..e5e136d5e0d 100644 --- a/pkg/storage/utils/decomposedfs/tree/tree.go +++ b/pkg/storage/utils/decomposedfs/tree/tree.go @@ -40,7 +40,7 @@ import ( "github.com/rs/zerolog/log" ) -//go:generate mockery -name Blobstore +// go:generate mockery -name Blobstore // Blobstore defines an interface for storing blobs in a blobstore type Blobstore interface { diff --git a/pkg/storage/utils/localfs/upload.go b/pkg/storage/utils/localfs/upload.go index 95905d2f0f7..d19556fc432 100644 --- a/pkg/storage/utils/localfs/upload.go +++ b/pkg/storage/utils/localfs/upload.go @@ -329,7 +329,7 @@ func (upload *fileUpload) FinishUpload(ctx context.Context) error { // TODO check etag with If-Match header // if destination exists - //if _, err := os.Stat(np); err == nil { + // if _, err := os.Stat(np); err == nil { // the local storage does not store metadata // the fileid is based on the path, so no we do not need to copy it to the new file // the local storage does not track revisions diff --git a/pkg/storage/utils/templates/templates_test.go b/pkg/storage/utils/templates/templates_test.go index aa5cea452f1..4ae236a4972 100644 --- a/pkg/storage/utils/templates/templates_test.go +++ b/pkg/storage/utils/templates/templates_test.go @@ -116,7 +116,7 @@ func testBadLayout() { WithUser(user, layout) } -//should panic +// should panic func testBadUser() { layout := "{{ .DoesNotExist }}" user := &userpb.User{} diff --git a/pkg/utils/utils.go b/pkg/utils/utils.go index e3bd4ab24c8..88b50aa7854 100644 --- a/pkg/utils/utils.go +++ b/pkg/utils/utils.go @@ -32,6 +32,8 @@ import ( userpb "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1" provider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1" types "github.com/cs3org/go-cs3apis/cs3/types/v1beta1" + "github.com/golang/protobuf/proto" + "google.golang.org/protobuf/encoding/protojson" ) var ( @@ -161,8 +163,25 @@ func GranteeEqual(u, v *provider.Grantee) bool { // IsEmailValid checks whether the provided email has a valid format. func IsEmailValid(e string) bool { - if len(e) < 3 && len(e) > 254 { + if len(e) < 3 || len(e) > 254 { return false } return matchEmail.MatchString(e) } + +// MarshalProtoV1ToJSON marshals a proto V1 message to a JSON byte array +// TODO: update this once we start using V2 in CS3APIs +func MarshalProtoV1ToJSON(m proto.Message) ([]byte, error) { + mV2 := proto.MessageV2(m) + return protojson.Marshal(mV2) +} + +// UnmarshalJSONToProtoV1 decodes a JSON byte array to a specified proto message type +// TODO: update this once we start using V2 in CS3APIs +func UnmarshalJSONToProtoV1(b []byte, m proto.Message) error { + mV2 := proto.MessageV2(m) + if err := protojson.Unmarshal(b, mV2); err != nil { + return err + } + return nil +} diff --git a/tools/create-artifacts/main.go b/tools/create-artifacts/main.go index 79067c17719..9b94182961d 100644 --- a/tools/create-artifacts/main.go +++ b/tools/create-artifacts/main.go @@ -113,10 +113,11 @@ func hashFile(file string) { if err != nil { log.Fatal(err) } - defer f.Close() if _, err := io.Copy(hasher, f); err != nil { + f.Close() log.Fatal(err) } + f.Close() val := hex.EncodeToString(hasher.Sum(nil)) if err := ioutil.WriteFile(file+".sha256", []byte(val), 0644); err != nil { log.Fatal(err) diff --git a/tools/prepare-release/main.go b/tools/prepare-release/main.go index 1e5d7d22330..051909b04bd 100644 --- a/tools/prepare-release/main.go +++ b/tools/prepare-release/main.go @@ -97,10 +97,10 @@ func main() { fmt.Fprintf(os.Stderr, "error creating tmp directory to store changelog: %s", err) os.Exit(1) } - defer os.RemoveAll(tmp) if err := os.MkdirAll(path.Join(tmp, "changelog"), 0755); err != nil { fmt.Fprintf(os.Stderr, "error creating changelog in temporary directory: %s", tmp) + os.RemoveAll(tmp) os.Exit(1) } @@ -115,8 +115,10 @@ func main() { // Generate changelog also in the documentation if err := os.MkdirAll(fmt.Sprintf("docs/content/en/docs/changelog/%s", *version), 0755); err != nil { fmt.Fprintf(os.Stderr, "error creating docs/content/en/docs/changelog/%s: %s", *version, err) + os.RemoveAll(tmp) os.Exit(1) } + os.RemoveAll(tmp) data, err := ioutil.ReadFile("changelog/NOTE.md") if err != nil {