From 09801756aa405b976ad687ed698164faac211bb5 Mon Sep 17 00:00:00 2001 From: Joakim Bygdell Date: Wed, 24 Jul 2024 12:53:41 +0200 Subject: [PATCH] [api] add endpoint to list files for a specific user --- sda/cmd/api/api.go | 17 ++++++++++++++ sda/cmd/api/api_test.go | 50 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 67 insertions(+) diff --git a/sda/cmd/api/api.go b/sda/cmd/api/api.go index 37b0cf2a5..4841ea941 100644 --- a/sda/cmd/api/api.go +++ b/sda/cmd/api/api.go @@ -80,6 +80,7 @@ func setup(config *config.Config) *http.Server { r.POST("/dataset/create", isAdmin(), createDataset) // maps a set of files to a dataset r.POST("/dataset/release/*dataset", isAdmin(), releaseDataset) // Releases a dataset to be accessible r.GET("/users", isAdmin(), listActiveUsers) // Lists all users + r.GET("/users/:username/files", isAdmin(), listUserFiles) // Lists all unmapped files for a user cfg := &tls.Config{MinVersion: tls.VersionTLS12} @@ -379,3 +380,19 @@ func listActiveUsers(c *gin.Context) { } c.JSON(http.StatusOK, users) } + +func listUserFiles(c *gin.Context) { + username := c.Param("username") + username = strings.TrimPrefix(username, "/") + username = strings.TrimSuffix(username, "/files") + log.Debugln(username) + files, err := Conf.API.DB.GetUserFiles(username) + if err != nil { + c.AbortWithStatusJSON(http.StatusInternalServerError, err.Error()) + + return + } + + c.Writer.Header().Set("Content-Type", "application/json") + c.JSON(200, files) +} diff --git a/sda/cmd/api/api_test.go b/sda/cmd/api/api_test.go index a8b711c3f..367b0d4ee 100644 --- a/sda/cmd/api/api_test.go +++ b/sda/cmd/api/api_test.go @@ -1146,3 +1146,53 @@ func (suite *TestSuite) TestListActiveUsers() { assert.NoError(suite.T(), err, "failed to list users from DB") assert.Equal(suite.T(), []string{"User-B", "User-C"}, users) } + +func (suite *TestSuite) TestListUserFiles() { + testUsers := []string{"User-A", "User-B", "User-C"} + for _, user := range testUsers { + for i := 0; i < 5; i++ { + fileID, err := Conf.API.DB.RegisterFile(fmt.Sprintf("/%v/TestGetUserFiles-00%d.c4gh", user, i), user) + if err != nil { + suite.FailNow("failed to register file in database") + } + + err = Conf.API.DB.UpdateFileEventLog(fileID, "uploaded", fileID, user, "{}", "{}") + if err != nil { + suite.FailNow("failed to update satus of file in database") + } + + stableID := fmt.Sprintf("accession_%s_0%d", user, i) + err = Conf.API.DB.SetAccessionID(stableID, fileID) + if err != nil { + suite.FailNowf("got (%s) when setting stable ID: %s, %s", err.Error(), stableID, fileID) + } + } + } + + err = Conf.API.DB.MapFilesToDataset("test-dataset-01", []string{"accession_User-A_00", "accession_User-A_01", "accession_User-A_02"}) + if err != nil { + suite.FailNow("failed to map files to dataset") + } + + gin.SetMode(gin.ReleaseMode) + assert.NoError(suite.T(), setupJwtAuth()) + Conf.API.Admins = []string{"dummy"} + + // Mock request and response holders + w := httptest.NewRecorder() + r := httptest.NewRequest(http.MethodGet, "/users/User-A/files", http.NoBody) + r.Header.Add("Authorization", "Bearer "+suite.Token) + + _, router := gin.CreateTestContext(w) + router.GET("/users/:username/files", isAdmin(), listUserFiles) + + router.ServeHTTP(w, r) + okResponse := w.Result() + defer okResponse.Body.Close() + assert.Equal(suite.T(), http.StatusOK, okResponse.StatusCode) + + files := []database.SubmissionFileInfo{} + err = json.NewDecoder(okResponse.Body).Decode(&files) + assert.NoError(suite.T(), err, "failed to list users from DB") + assert.Equal(suite.T(), 5, len(files)) +}