bitflicker64 commented on code in PR #3189:
URL: https://github.com/apache/hugegraph/pull/3189#discussion_r3934249764


##########
docker/conf/hubble/hstore.properties:
##########
@@ -20,6 +20,11 @@ pd.enabled=true
 server.direct_url=http://server:8080
 pd.peers=pd:8686
 pd.server=pd:8620
+# PD REST credential. The password must equal PD's auth.secret-key, which has
+# no default: set it to the same value as HG_PD_AUTH_SECRET_KEY in .env. While
+# it is empty, Hubble's PD-backed views get HTTP 401 from PD.
+operations.pd.username=hubble
+operations.pd.password=

Review Comment:
   ⚠️ Hubble has no path from `.env` to this value, so its PD-backed views 
answer 401 in both shipped HStore stacks. The fix spans `docker/README.md`, the 
two compose files and `.gitignore`, not just this line.
   
   `docker-compose-hstore.yml:120` mounts this file verbatim 
(`./conf/hubble/hstore.properties:/hubble/conf/hugegraph-hubble.properties:ro`),
 and `docker-compose-3pd-3store-3server.yml:239` does the same for 
`hstore-ha.properties`. Compose does not interpolate properties files, and the 
`hugegraph/hubble` image has no entrypoint that rewrites config from the 
environment: hugegraph-toolchain ships only `hugegraph-hubble/Dockerfile`, 
whose `ENTRYPOINT` is `./bin/start-hubble.sh -f`, and `operations.pd.password` 
is read through `HubbleOptions` into a `HugeConfig` from the file, not through 
Spring relaxed binding. The Server gets the secret via `PD_AUTH_PASSWORD: 
${HG_PD_AUTH_SECRET_KEY:?...}`; Hubble gets nothing.
   
   The remedy `docker/README.md` documents is `sed -i.bak` over this file, 
which is tracked in git. That has an operator write a production secret into a 
tracked file in their clone, one `git add -A` away from being committed. 
`hstore-ha.properties:27` is identical.
   
   Requested change: imbajin already asked for a safe config-generation path on 
`docker/README.md:107`. When you build it, have it generate an untracked file 
rather than edit this one in place: ship 
`conf/hubble/hstore.properties.example`, generate 
`conf/hubble/hstore.local.properties` from it in the same step that writes 
`.env`, point the compose mount there, and add 
`docker/conf/hubble/*.local.properties` to `.gitignore` next to the existing 
`docker/.env` entry. The generation step has to run before `docker compose up`, 
otherwise Docker creates an empty directory at the bind path and Hubble starts 
with no config at all.



##########
hugegraph-pd/hg-pd-core/src/main/java/org/apache/hugegraph/pd/config/PDConfig.java:
##########
@@ -85,6 +98,17 @@ public class PDConfig {
     private ConfigService configService;
     private IdService idService;
 
+    @Override
+    public void afterPropertiesSet() {
+        if (PUBLISHED_SECRET_KEY.equals(this.secretKey)) {

Review Comment:
   🧹 Follow-on to the resolved `Authentication.java:112` thread, not a 
reopening of it: the one-shot ERROR you added in `verifySecret` fires on the 
first authenticated request, so it can arrive long after the misconfiguration, 
or never.
   
   This check rejects only `PUBLISHED_SECRET_KEY`. The empty case is the one 
both shipped `application.yml` files now produce, and it starts silently. 
Meanwhile the shipped PD healthchecks are `curl -fsS 
http://localhost:8620/v1/health`, which `AuthenticationConfigurer` excludes, so 
a PD with no secret reports healthy while refusing every real REST call. An 
operator sees it only as a client-side 401 or as the 300s `wait-storage.sh` 
timeout.
   
   Requested change: log it here too. `afterPropertiesSet` is already the 
startup hook, so adding `@Slf4j` to `PDConfig` and an `else if 
(StringUtils.isEmpty(this.secretKey))` branch that emits the same 
"auth.secret-key is not configured" message puts the condition in the boot log 
rather than only on first use. Throwing instead, for symmetry with the 
entrypoint's `require_env "HG_PD_AUTH_SECRET_KEY"`, would also work if you are 
willing to make it a hard upgrade gate.



##########
hugegraph-server/hugegraph-dist/src/assembly/static/bin/wait-storage.sh:
##########
@@ -101,10 +119,12 @@ if env | grep '^hugegraph\.' > /dev/null; then
 
               check_any_pd_stores() {
                 for peer in \$(echo \"\$PD_REST_LIST\" | tr ',' ' '); do
-                  if curl ${PD_AUTH_ARGS} -f -s \
+                  if printf 'user = \"%s:%s\"\n' \
+                       \"\$PD_AUTH_CURL_USER\" \"\$PD_AUTH_CURL_PASSWORD\" | \
+                     curl -K - -f -s \

Review Comment:
   ⚠️ A 401 from PD is indistinguishable here from "PD unreachable" and from 
"no store is Up", so a missing or stale secret surfaces as a storage-backend 
failure.
   
   curl's exit status never reaches the `if`: lines 122-128 are `printf ... | 
curl ... | grep -qi '"state"...'`, and neither this script, `util.sh`, nor the 
inner `bash -c` sets `pipefail`, so the `if` tests grep alone. On a 401 the 
body is `{"status":-1,"error":"..."}`, grep finds no `"state": "Up"`, and the 
`until` loop sleeps 5s and retries until `timeout` fires. The operator's only 
signal is `ERROR: Timeout waiting for storage backend` after 
`WAIT_STORAGE_TIMEOUT_S` (300s, line 32), which names the wrong subsystem. The 
`WARN` at line 50 fires only when `PD_AUTH_PASSWORD` is empty, not when it is 
set to the wrong value.
   
   This is now the default first-boot path for anything outside the two updated 
compose files: a stock PD tarball ships `secret-key:` empty, so it refuses 
`/v1/stores`, and a stock Server then hangs five minutes and exits 1 pointing 
at storage.
   
   Requested change: take curl out of the pipeline so its status code is 
readable, and abort on 401 instead of retrying. Roughly:
   
   ```sh
   body=$(printf 'user = "%s:%s"\n' "$PD_AUTH_CURL_USER" 
"$PD_AUTH_CURL_PASSWORD" |
           curl -K - -s -w '\n%{http_code}' --connect-timeout 2 --max-time 3 \
                "http://${peer}/v1/stores"; 2>/dev/null)
   code=${body##*$'\n'}
   if [ "$code" = 401 ]; then
     echo "PD at ${peer} refused the credential (401): PD_AUTH_PASSWORD must 
match PD's"
     echo "auth.secret-key"
     exit 1
   fi
   ```
   
   then grep the body as before. Adding `-w` to the existing pipeline would not 
help, since the code would be appended to the very stdout that feeds grep.



##########
hugegraph-pd/hg-pd-service/src/main/java/org/apache/hugegraph/pd/rest/interceptor/RestAuthentication.java:
##########
@@ -59,6 +59,10 @@ public boolean preHandle(HttpServletRequest request, 
HttpServletResponse respons
             authority = authority.replace("Basic ", "");
             return authenticate(authority, token, tokenCall, DEFAULT_HANDLE);
         } catch (Exception e) {
+            response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
+            // RFC 7235 requires a challenge on a 401; without it clients that
+            // authenticate reactively never retry with credentials
+            response.setHeader("WWW-Authenticate", "Basic 
realm=\"hugegraph-pd\"");
             response.setContentType("application/json");
             response.getWriter().println(new API().toJSON(e));

Review Comment:
   🧹 The 401 body echoes the internal exception class to unauthenticated 
callers.
   
   `API.toJSON(Throwable)` (API.java:127) emits `exception.getMessage()`, and 
`Authentication.authenticate` rethrows as `new RuntimeException(e)`, whose 
message is `cause.toString()` per `Throwable(Throwable)`. So a caller with no 
valid credential gets a body equivalent to (key order is Jackson's over a 
`HashMap`, so not fixed):
   
   ```json
   
{"status":-1,"error":"org.springframework.security.authentication.BadCredentialsException:
 invalid credential"}
   ```
   
   and `...AccessDeniedException: invalid service name` for a name outside 
`innerModules`. That puts internal class names on an unauthenticated path and 
distinguishes "unknown service name" from "wrong password".
   
   Requested change: write a constant body on this path, 
`{"status":-1,"error":"Unauthorized"}`, and move the specific reason to a 
server-side `log.debug` or `log.warn`.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to