diff --git a/cache/handler/cache.go b/cache/handler/cache.go index 2f7f5d8..2ab6fc4 100644 --- a/cache/handler/cache.go +++ b/cache/handler/cache.go @@ -144,7 +144,7 @@ func (c *Cache) DeleteData(ctx context.Context, request *adminpb.DeleteDataReque return err } - if len(request.TenantId) == 0 { + if len(request.TenantId) < 10 { // deliberate length check so we don't delete all the things return errors.BadRequest(method, "Missing tenant ID") } diff --git a/contact/handler/contact.go b/contact/handler/contact.go index 2f2c7a5..d5c960c 100644 --- a/contact/handler/contact.go +++ b/contact/handler/contact.go @@ -137,7 +137,7 @@ func (c *contact) DeleteData(ctx context.Context, request *adminpb.DeleteDataReq return err } - if len(request.TenantId) == 0 { + if len(request.TenantId) < 10 { // deliberate length check so we don't delete all the things return errors.BadRequest(method, "Missing tenant ID") } diff --git a/db/handler/db.go b/db/handler/db.go index d582286..301923e 100644 --- a/db/handler/db.go +++ b/db/handler/db.go @@ -451,7 +451,7 @@ func (e *Db) DeleteData(ctx context.Context, request *adminpb.DeleteDataRequest, return err } - if len(request.TenantId) == 0 { + if len(request.TenantId) < 10 { // deliberate length check so we don't delete all the things return errors.BadRequest(method, "Missing tenant ID") } diff --git a/file/handler/files.go b/file/handler/files.go index 9cc7df8..857b326 100644 --- a/file/handler/files.go +++ b/file/handler/files.go @@ -160,7 +160,7 @@ func (e *File) DeleteData(ctx context.Context, request *adminpb.DeleteDataReques return err } - if len(request.TenantId) == 0 { + if len(request.TenantId) < 10 { // deliberate length check so we don't delete all the things return errors.BadRequest(method, "Missing tenant ID") } diff --git a/location/handler/handler.go b/location/handler/handler.go index 107f56b..7ef70b9 100644 --- a/location/handler/handler.go +++ b/location/handler/handler.go @@ -81,7 +81,7 @@ func (l *Location) DeleteData(ctx context.Context, request *adminpb.DeleteDataRe return err } - if len(request.TenantId) == 0 { + if len(request.TenantId) < 10 { // deliberate length check so we don't delete all the things return errors.BadRequest(method, "Missing tenant ID") } diff --git a/notes/handler/notes.go b/notes/handler/notes.go index f85b281..214a383 100644 --- a/notes/handler/notes.go +++ b/notes/handler/notes.go @@ -303,7 +303,7 @@ func (h *Notes) DeleteData(ctx context.Context, request *adminpb.DeleteDataReque return err } - if len(request.TenantId) == 0 { + if len(request.TenantId) < 10 { // deliberate length check so we don't delete all the things return errors.BadRequest(method, "Missing tenant ID") } diff --git a/rss/handler/rss.go b/rss/handler/rss.go index 8b8c0f6..1a9c387 100644 --- a/rss/handler/rss.go +++ b/rss/handler/rss.go @@ -186,7 +186,7 @@ func (e *Rss) DeleteData(ctx context.Context, request *adminpb.DeleteDataRequest return err } - if len(request.TenantId) == 0 { + if len(request.TenantId) < 10 { // deliberate length check so we don't delete all the things return errors.BadRequest(method, "Missing tenant ID") } split := strings.Split(request.TenantId, "/") diff --git a/search/handler/search.go b/search/handler/search.go index e108ed2..5858066 100644 --- a/search/handler/search.go +++ b/search/handler/search.go @@ -16,6 +16,8 @@ import ( "github.com/micro/micro/v3/service/config" "github.com/micro/micro/v3/service/errors" log "github.com/micro/micro/v3/service/logger" + pauth "github.com/micro/services/pkg/auth" + adminpb "github.com/micro/services/pkg/service/proto" "github.com/micro/services/pkg/tenant" pb "github.com/micro/services/search/proto" open "github.com/opensearch-project/opensearch-go" @@ -55,6 +57,10 @@ type hit struct { Source map[string]interface{} `json:"_source"` } +type catIndicesEntry struct { + Index string `json:"index"` +} + func New(srv *service.Service) *Search { v, err := config.Get("micro.search") if err != nil { @@ -280,8 +286,12 @@ func (s *Search) DeleteIndex(ctx context.Context, request *pb.DeleteIndexRequest if len(request.Index) == 0 { return errors.BadRequest(method, "Missing index param") } + return s.deleteIndices(ctx, []string{indexName(tnt, request.Index)}, method) +} + +func (s *Search) deleteIndices(ctx context.Context, indices []string, method string) error { req := openapi.IndicesDeleteRequest{ - Index: []string{indexName(tnt, request.Index)}, + Index: indices, } rsp, err := req.Do(ctx, s.client) if err != nil { @@ -293,5 +303,48 @@ func (s *Search) DeleteIndex(ctx context.Context, request *pb.DeleteIndexRequest log.Errorf("Error deleting index %s", rsp.String()) return errors.InternalServerError(method, "Error deleting index") } + log.Infof("Deleted indices: %v", indices) return nil + +} + +func (s *Search) DeleteData(ctx context.Context, request *adminpb.DeleteDataRequest, response *adminpb.DeleteDataResponse) error { + method := "admin.DeleteData" + _, err := pauth.VerifyMicroAdmin(ctx, method) + if err != nil { + return err + } + + if len(request.TenantId) < 10 { // deliberate length check, don't want to unwittingly delete all the things + return errors.BadRequest(method, "Missing tenant ID") + } + req := openapi.CatIndicesRequest{ + Format: "json", + } + rsp, err := req.Do(ctx, s.client) + if err != nil { + return err + } + defer rsp.Body.Close() + if rsp.IsError() { + return err + } + b, err := ioutil.ReadAll(rsp.Body) + if err != nil { + return err + } + + var entries []catIndicesEntry + if err := json.Unmarshal(b, &entries); err != nil { + return err + } + toDelete := []string{} + for _, entry := range entries { + if !strings.HasPrefix(entry.Index, indexName(request.TenantId, "")) { + continue + } + toDelete = append(toDelete, entry.Index) + + } + return s.deleteIndices(ctx, toDelete, method) } diff --git a/search/main.go b/search/main.go index f2ce90f..a8d862c 100644 --- a/search/main.go +++ b/search/main.go @@ -3,6 +3,7 @@ package main import ( "github.com/micro/micro/v3/service" "github.com/micro/micro/v3/service/logger" + admin "github.com/micro/services/pkg/service/proto" "github.com/micro/services/search/handler" pb "github.com/micro/services/search/proto" ) @@ -14,8 +15,10 @@ func main() { service.Version("latest"), ) + h := handler.New(srv) // Register handler - pb.RegisterSearchHandler(srv.Server(), handler.New(srv)) + pb.RegisterSearchHandler(srv.Server(), h) + admin.RegisterAdminHandler(srv.Server(), h) // Run service if err := srv.Run(); err != nil { diff --git a/space/handler/space.go b/space/handler/space.go index 6aeb8cb..aad78b0 100644 --- a/space/handler/space.go +++ b/space/handler/space.go @@ -15,6 +15,8 @@ import ( "github.com/micro/micro/v3/service/errors" log "github.com/micro/micro/v3/service/logger" "github.com/micro/micro/v3/service/store" + pauth "github.com/micro/services/pkg/auth" + adminpb "github.com/micro/services/pkg/service/proto" "github.com/micro/services/pkg/tenant" pb "github.com/micro/services/space/proto" "github.com/minio/minio-go/v7/pkg/s3utils" @@ -503,3 +505,56 @@ func (s Space) Upload(ctx context.Context, request *pb.UploadRequest, response * return nil } + +func (s Space) DeleteData(ctx context.Context, request *adminpb.DeleteDataRequest, response *adminpb.DeleteDataResponse) error { + method := "admin.DeleteData" + _, err := pauth.VerifyMicroAdmin(ctx, method) + if err != nil { + return err + } + + if len(request.TenantId) < 10 { // deliberate length check so we don't delete all the things + return errors.BadRequest(method, "Missing tenant ID") + } + + objectName := request.TenantId + rsp, err := s.client.ListObjects(&sthree.ListObjectsInput{ + Bucket: aws.String(s.conf.SpaceName), + Prefix: aws.String(objectName), + }) + if err != nil { + log.Errorf("Error listing objects %s", err) + return errors.InternalServerError(method, "Error listing objects") + } + + oIDs := []*sthree.ObjectIdentifier{} + for _, v := range rsp.Contents { + oIDs = append(oIDs, &sthree.ObjectIdentifier{Key: v.Key}) + } + + if _, err := s.client.DeleteObjects(&sthree.DeleteObjectsInput{ + Bucket: aws.String(s.conf.SpaceName), + Delete: &sthree.Delete{ + Objects: oIDs, + }, + }); err != nil { + return err + } + + log.Infof("Deleted %d objects from s3 for %s", len(oIDs), request.TenantId) + + keys, err := store.List(store.ListPrefix(fmt.Sprintf("%s/", prefixByUser))) + if err != nil { + log.Errorf("Error listing objects %s", err) + return errors.InternalServerError(method, "Error listing objects") + } + for _, k := range keys { + if err := store.Delete(k); err != nil { + return err + } + } + log.Infof("Deleted %d objects from store for %s", len(keys), request.TenantId) + + return nil + +} diff --git a/space/main.go b/space/main.go index 7ddd74d..8e1e2e5 100644 --- a/space/main.go +++ b/space/main.go @@ -4,6 +4,7 @@ import ( "github.com/micro/micro/v3/service" "github.com/micro/micro/v3/service/api" "github.com/micro/micro/v3/service/logger" + admin "github.com/micro/services/pkg/service/proto" "github.com/micro/services/space/handler" ) @@ -14,12 +15,12 @@ func main() { service.Version("latest"), ) + h := handler.NewSpace(srv) // Register handler - //pb.RegisterSpaceHandler(srv.Server(), handler.NewSpace(srv)) - + admin.RegisterAdminHandler(srv.Server(), h) srv.Server().Handle( srv.Server().NewHandler( - handler.NewSpace(srv), + h, api.WithEndpoint( &api.Endpoint{ Name: "Space.Download", diff --git a/user/handler/handler.go b/user/handler/handler.go index a1935f5..03fdeeb 100644 --- a/user/handler/handler.go +++ b/user/handler/handler.go @@ -514,7 +514,7 @@ func (s *User) DeleteData(ctx context.Context, request *adminpb.DeleteDataReques return err } - if len(request.TenantId) == 0 { + if len(request.TenantId) < 10 { // deliberate length check so we don't delete all the things return errors.BadRequest("user.DeleteData", "Missing tenant ID") } return s.domain.DeleteTenantData(request.TenantId)