|
|
@@ -257,3 +257,51 @@ TEST_F(ApiFixture, CannotDeAdminLastAdminKey) {
|
|
|
ASSERT_TRUE(check);
|
|
|
EXPECT_EQ(check->status, 200);
|
|
|
}
|
|
|
+
|
|
|
+// W9 Step 1a: GET /api/v1/settings masks the secret
|
|
|
+TEST_F(ApiFixture, SettingsGetMasksSecretForAdmin) {
|
|
|
+ auto r = admin().Get("/api/v1/settings");
|
|
|
+ ASSERT_TRUE(r);
|
|
|
+ ASSERT_EQ(r->status, 200);
|
|
|
+ auto body = nlohmann::json::parse(r->body);
|
|
|
+ // Must have the masking bool but NOT the raw secret
|
|
|
+ EXPECT_TRUE(body.contains("openai_api_key_set"));
|
|
|
+ EXPECT_FALSE(body.contains("openai_api_key"));
|
|
|
+ // The fixture sets a non-empty key so openai_api_key_set must be true
|
|
|
+ EXPECT_TRUE(body["openai_api_key_set"].get<bool>());
|
|
|
+ // Other fields must be present
|
|
|
+ EXPECT_TRUE(body.contains("openai_api_base"));
|
|
|
+ EXPECT_TRUE(body.contains("default_embedding_model"));
|
|
|
+}
|
|
|
+
|
|
|
+// W9 Step 1a: PUT /api/v1/settings changes a field; non-admin gets 403
|
|
|
+TEST_F(ApiFixture, SettingsPutChangesField) {
|
|
|
+ // Change default_embedding_model
|
|
|
+ auto put = admin().Put("/api/v1/settings",
|
|
|
+ nlohmann::json{{"default_embedding_model", "text-embedding-3-large"}}.dump(), "application/json");
|
|
|
+ ASSERT_TRUE(put);
|
|
|
+ ASSERT_EQ(put->status, 200);
|
|
|
+ auto putBody = nlohmann::json::parse(put->body);
|
|
|
+ EXPECT_TRUE(putBody["ok"].get<bool>());
|
|
|
+
|
|
|
+ // GET and verify the change
|
|
|
+ auto get = admin().Get("/api/v1/settings");
|
|
|
+ ASSERT_TRUE(get);
|
|
|
+ ASSERT_EQ(get->status, 200);
|
|
|
+ auto getBody = nlohmann::json::parse(get->body);
|
|
|
+ EXPECT_EQ(getBody["default_embedding_model"].get<std::string>(), "text-embedding-3-large");
|
|
|
+
|
|
|
+ // A scoped (non-admin) key must get 403 on GET
|
|
|
+ auto mk = admin().Post("/api/v1/keys",
|
|
|
+ nlohmann::json{{"label","scoped"},{"projects",{project_}},{"admin",false}}.dump(), "application/json");
|
|
|
+ ASSERT_TRUE(mk); ASSERT_EQ(mk->status, 201);
|
|
|
+ std::string scopedKey = nlohmann::json::parse(mk->body)["key"];
|
|
|
+ auto denied = http(scopedKey).Get("/api/v1/settings");
|
|
|
+ ASSERT_TRUE(denied);
|
|
|
+ EXPECT_EQ(denied->status, 403);
|
|
|
+ admin().Delete(("/api/v1/keys/" + scopedKey).c_str());
|
|
|
+
|
|
|
+ // Restore original model so other tests are unaffected
|
|
|
+ admin().Put("/api/v1/settings",
|
|
|
+ nlohmann::json{{"default_embedding_model", "text-embedding-3-small"}}.dump(), "application/json");
|
|
|
+}
|