From 2cff4cf0bbd4c7e35cbae591a50d520449a932f5 Mon Sep 17 00:00:00 2001 From: "A.Unger" Date: Fri, 23 Apr 2021 13:35:01 +0200 Subject: [PATCH] rework of PR#755 --- .drone.star | 2 +- ocs/pkg/service/v0/users.go | 111 ++++++++++++++++++++++++++++++++++-- 2 files changed, 107 insertions(+), 6 deletions(-) diff --git a/.drone.star b/.drone.star index 532558c391..841270a779 100644 --- a/.drone.star +++ b/.drone.star @@ -454,7 +454,7 @@ def localApiTests(ctx, storage = 'owncloud', suite = 'apiBugDemonstration', acco 'environment' : { 'TEST_SERVER_URL': 'https://ocis-server:9200', 'OCIS_REVA_DATA_ROOT': '%s' % ('/srv/app/tmp/ocis/owncloud/data/' if storage == 'owncloud' else ''), - 'DELETE_USER_DATA_CMD': '%s' % ('' if storage == 'owncloud' else 'rm -rf /srv/app/tmp/ocis/storage/users/nodes/root/* /srv/app/tmp/ocis/storage/users/nodes/*-*-*-*'), + #'DELETE_USER_DATA_CMD': '%s' % ('' if storage == 'owncloud' else 'rm -rf /srv/app/tmp/ocis/storage/users/nodes/root/* /srv/app/tmp/ocis/storage/users/nodes/*-*-*-*'), 'SKELETON_DIR': '/srv/app/tmp/testing/data/apiSkeleton', 'OCIS_SKELETON_STRATEGY': '%s' % ('copy' if storage == 'owncloud' else 'upload'), 'TEST_OCIS':'true', diff --git a/ocs/pkg/service/v0/users.go b/ocs/pkg/service/v0/users.go index ac25d0541d..335cc3cb3d 100644 --- a/ocs/pkg/service/v0/users.go +++ b/ocs/pkg/service/v0/users.go @@ -10,18 +10,26 @@ import ( "strings" "github.com/asim/go-micro/plugins/client/grpc/v3" + merrors "github.com/asim/go-micro/v3/errors" + cs3 "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1" + revauser "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1" + rpcv1beta1 "github.com/cs3org/go-cs3apis/cs3/rpc/v1beta1" + provider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1" + types "github.com/cs3org/go-cs3apis/cs3/types/v1beta1" + "github.com/cs3org/reva/pkg/rgrpc/todo/pool" + "github.com/cs3org/reva/pkg/token" + "github.com/cs3org/reva/pkg/token/manager/jwt" "github.com/cs3org/reva/pkg/user" "github.com/go-chi/chi" "github.com/go-chi/render" - "google.golang.org/genproto/protobuf/field_mask" - "google.golang.org/protobuf/types/known/fieldmaskpb" - - merrors "github.com/asim/go-micro/v3/errors" - cs3 "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1" accounts "github.com/owncloud/ocis/accounts/pkg/proto/v0" "github.com/owncloud/ocis/ocs/pkg/service/v0/data" "github.com/owncloud/ocis/ocs/pkg/service/v0/response" storepb "github.com/owncloud/ocis/store/pkg/proto/v0" + "github.com/pkg/errors" + "google.golang.org/genproto/protobuf/field_mask" + "google.golang.org/grpc/metadata" + "google.golang.org/protobuf/types/known/fieldmaskpb" ) // GetSelf returns the currently logged in user @@ -358,6 +366,70 @@ func (o Ocs) DeleteUser(w http.ResponseWriter, r *http.Request) { return } + // Note that the previous conditional is short circuiting this. This logic will NOT run when the user's backend is + // configured to use any other than the accounts service. + t, err := o.mintTokenForUser(r.Context(), account) + if err != nil { + render.Render(w, r, response.ErrRender(data.MetaServerError.StatusCode, errors.Wrap(err, "could not mint token").Error())) + return + } + + ctx := metadata.AppendToOutgoingContext(r.Context(), token.TokenHeader, t) + + gwc, err := pool.GetGatewayServiceClient(o.config.RevaAddress) + if err != nil { + o.logger.Error().Err(err).Msg("error securing a connection to the reva gateway, could not delete user home") + } + + homeResp, err := gwc.GetHome(ctx, &provider.GetHomeRequest{}) + if err != nil { + render.Render(w, r, response.ErrRender(data.MetaServerError.StatusCode, errors.Wrap(err, "could not get home").Error())) + return + } + + statResp, err := gwc.Stat(ctx, &provider.StatRequest{ + Ref: &provider.Reference{ + Spec: &provider.Reference_Path{ + Path: homeResp.Path, + }, + }, + }) + + if err != nil { + render.Render(w, r, response.ErrRender(data.MetaServerError.StatusCode, errors.Wrap(err, "could not stat home").Error())) + return + } + + if statResp.Status.Code != rpcv1beta1.Code_CODE_OK { + o.logger.Error(). + Str("stat_status_code", statResp.Status.Code.String()). + Str("stat_message", statResp.Status.Message). + Msg("DeleteUser: could not delete user home: stat failed") + return + } + + delReq := &provider.DeleteRequest{ + Ref: &provider.Reference{ + Spec: &provider.Reference_Id{ + Id: statResp.Info.Id, + }, + }, + } + + delResp, err := gwc.Delete(ctx, delReq) + if err != nil { + render.Render(w, r, response.ErrRender(data.MetaServerError.StatusCode, errors.Wrap(err, "could not delete home").Error())) + return + } + + if delResp.Status.Code != rpcv1beta1.Code_CODE_OK { + o.logger.Error(). + Str("stat_status_code", statResp.Status.Code.String()). + Str("stat_message", statResp.Status.Message). + Msg("DeleteUser: could not delete user home: delete failed") + return + } + req := accounts.DeleteAccountRequest{ Id: account.Id, } @@ -378,6 +450,35 @@ func (o Ocs) DeleteUser(w http.ResponseWriter, r *http.Request) { mustNotFail(render.Render(w, r, response.DataRender(struct{}{}))) } +// TODO(refs) this to ocis-pkg ... we are minting tokens all over the place ... or use a service? ... like reva? +func (o Ocs) mintTokenForUser(ctx context.Context, account *accounts.Account) (string, error) { + tm, _ := jwt.New(map[string]interface{}{ + "secret": "Pive-Fumkiu4", // TODO(refs) this MUST not be hardcoded + "expires": int64(60), + }) + + u := &revauser.User{ + Id: &revauser.UserId{ + OpaqueId: account.Id, + Idp: "https://localhost:9200", // TODO(refs) this MUST not be hardcoded + }, + Groups: []string{}, + Opaque: &types.Opaque{ + Map: map[string]*types.OpaqueEntry{ + "uid": { + Decoder: "plain", + Value: []byte(strconv.FormatInt(account.UidNumber, 10)), + }, + "gid": { + Decoder: "plain", + Value: []byte(strconv.FormatInt(account.GidNumber, 10)), + }, + }, + }, + } + return tm.MintToken(ctx, u) +} + // EnableUser enables a user func (o Ocs) EnableUser(w http.ResponseWriter, r *http.Request) { userid := chi.URLParam(r, "userid")