Skip to content

Commit

Permalink
Re-use basenames for an already-registered directory if base= is absent.
Browse files Browse the repository at this point in the history
This allows users to easily update the index for an already-registered
directory by just re-registering it without having to keep track of the
basenames that were used in the initial registration call.
  • Loading branch information
LTLA committed Oct 20, 2024
1 parent 28091cb commit 7c61327
Show file tree
Hide file tree
Showing 5 changed files with 149 additions and 2 deletions.
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,8 @@ The caller is expected to verify that they have write access to the specified di

Once this is done, we call the `/register/finish` endpoint with a JSON-encoded request body that contains the same directory path in `path`.
The body may also contain `base`, an array of strings containing the names of the metadata files in the directory to be indexed.
If `base` is not provided, only files named `metadata.json` will be indexed.
If `base` is not provided and `path` has already been registered, the `base` associated with `path`'s prior registration is re-used;
otherwise, if `path` was not previously registered, only files named `metadata.json` will be indexed.

```shell
curl -X POST -L ${SEWER_RAT_URL}/register/finish \
Expand Down
23 changes: 23 additions & 0 deletions database.go
Original file line number Diff line number Diff line change
Expand Up @@ -883,3 +883,26 @@ func isDirectoryRegistered(db * sql.DB, path string) (bool, error) {
}
return num > 0, nil
}

/**********************************************************************/

func fetchRegisteredDirectoryNames(db *sql.DB, path string) ([]string, error) {
row := db.QueryRow("SELECT json_extract(names, '$') FROM dirs WHERE path = ?", path)
var names_as_str string
err := row.Scan(&names_as_str)

if errors.Is(err, sql.ErrNoRows) {
return nil, nil
} else if err != nil {
return nil, fmt.Errorf("failed to extract existing names for %q; %w", path, err)
}

output := []string{}
err = json.Unmarshal([]byte(names_as_str), &output)
if err != nil {
return nil, fmt.Errorf("failed to parse existing names for %q; %w", path, err)
}

return output, nil
}

44 changes: 44 additions & 0 deletions database_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1946,3 +1946,47 @@ func TestIsDirectoryRegistered(t *testing.T) {
}
})
}

func TestFetchRegisteredDirectoryNames(t *testing.T) {
tmp, err := os.MkdirTemp("", "")
if err != nil {
t.Fatalf(err.Error())
}
defer os.RemoveAll(tmp)

dbpath := filepath.Join(tmp, "db.sqlite3")
dbconn, err := initializeDatabase(dbpath)
if err != nil {
t.Fatalf(err.Error())
}
defer dbconn.Close()

tokr, err := newUnicodeTokenizer(false)
if err != nil {
t.Fatalf(err.Error())
}

to_add := filepath.Join(tmp, "liella")
err = mockDirectory(to_add)
if err != nil {
t.Fatalf(err.Error())
}

comments, err := addNewDirectory(dbconn, to_add, []string{ "metadata.json", "other.json" }, "aaron", tokr)
if err != nil {
t.Fatalf(err.Error())
}
if len(comments) > 0 {
t.Fatalf("unexpected comments from the directory addition %v", comments)
}

out, err := fetchRegisteredDirectoryNames(dbconn, to_add)
if len(out) != 2 || out[0] != "metadata.json" || out[1] != "other.json" {
t.Fatalf("unexpected names for the registered directory")
}

out, err = fetchRegisteredDirectoryNames(dbconn, filepath.Join(tmp, "margarete"))
if len(out) != 0 {
t.Fatalf("unexpected names for a non-registered directory")
}
}
11 changes: 10 additions & 1 deletion handlers.go
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,16 @@ func newRegisterFinishHandler(db *sql.DB, verifier *verificationRegistry, tokeni
return
}
} else {
allowed = []string{ "metadata.json" }
existing, err := fetchRegisteredDirectoryNames(db, output.Path)
if err != nil {
dumpHttpErrorResponse(w, err)
return
}
if existing == nil {
allowed = []string{ "metadata.json" }
} else {
allowed = existing
}
}

code_info, err := checkVerificationCode(regpath, verifier, timeout)
Expand Down
70 changes: 70 additions & 0 deletions handlers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -366,6 +366,76 @@ func TestRegisterHandlers(t *testing.T) {
t.Fatalf("unexpected paths in the database %v", all_paths)
}
})

t.Run("register finish reuse names", func(t *testing.T) {
{
code := quickRegisterStart()
err := os.WriteFile(filepath.Join(to_add, code), []byte(""), 0644)
if err != nil {
t.Fatal(err)
}

handler := http.HandlerFunc(newRegisterFinishHandler(dbconn, verifier, tokr, 1))
rr := httptest.NewRecorder()
req := createJsonRequest("POST", "/register/finish", map[string]interface{}{ "path": to_add, "base": []string{ "alpha.json", "bravo.json" } }, t)
handler.ServeHTTP(rr, req)
if rr.Code != http.StatusOK {
t.Fatalf("should have succeeded")
}
}

// Re-registering with the same names.
{
code := quickRegisterStart()
err := os.WriteFile(filepath.Join(to_add, code), []byte(""), 0644)
if err != nil {
t.Fatal(err)
}

handler := http.HandlerFunc(newRegisterFinishHandler(dbconn, verifier, tokr, 1))
rr := httptest.NewRecorder()
req := createJsonRequest("POST", "/register/finish", map[string]interface{}{ "path": to_add }, t)
handler.ServeHTTP(rr, req)
if rr.Code != http.StatusOK {
t.Fatalf("should have succeeded")
}

all_paths, err := listDirs(dbconn)
if err != nil {
t.Fatal(err)
}
my_names, ok := all_paths[to_add]
if !ok || !equalStringArrays(my_names, []string{ "alpha.json", "bravo.json" }) {
t.Fatalf("unexpected paths in the database %v", my_names)
}
}

// Re-registering with different names, to check that it indeed gets overridden.
{
code := quickRegisterStart()
err := os.WriteFile(filepath.Join(to_add, code), []byte(""), 0644)
if err != nil {
t.Fatal(err)
}

handler := http.HandlerFunc(newRegisterFinishHandler(dbconn, verifier, tokr, 1))
rr := httptest.NewRecorder()
req := createJsonRequest("POST", "/register/finish", map[string]interface{}{ "path": to_add, "base": []string{ "metadata.json" } }, t)
handler.ServeHTTP(rr, req)
if rr.Code != http.StatusOK {
t.Fatalf("should have succeeded")
}

all_paths, err := listDirs(dbconn)
if err != nil {
t.Fatal(err)
}
my_names, ok := all_paths[to_add]
if !ok || !equalStringArrays(my_names, []string{ "metadata.json" }) {
t.Fatalf("unexpected paths in the database %v", my_names)
}
}
})
}

func TestDeregisterHandlers(t *testing.T) {
Expand Down

0 comments on commit 7c61327

Please sign in to comment.