{"record":{"id":"0bab216b1d11dff5","repo":"sigoden/dufs","slug":"not-found-user-user","errorCode":null,"errorMessage":"Not found user '{user}'","messagePattern":"Not found user '(.+?)'","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"src/auth.rs","lineNumber":166,"sourceCode":"            return (None, None);\n        }\n\n        if !guard_options && method == Method::OPTIONS {\n            return (None, Some(AccessPaths::new(AccessPerm::ReadOnly)));\n        }\n\n        if let Some(ap) = self.anonymous.as_ref() {\n            return (None, ap.guard(path, method));\n        }\n\n        (None, None)\n    }\n\n    pub fn generate_token(&self, path: &str, user: &str) -> Result<String> {\n        let (pass, _) = self\n            .users\n            .get(user)\n            .ok_or_else(|| anyhow!(\"Not found user '{user}'\"))?;\n        let exp = unix_now().as_millis() as u64 + TOKEN_EXPIRATION;\n        let message = format!(\"{path}:{exp}\");\n        let mut signing_key = derive_secret_key(user, pass);\n        let sig = signing_key.sign(message.as_bytes()).to_bytes();\n\n        let mut raw = Vec::with_capacity(64 + 8 + user.len());\n        raw.extend_from_slice(&sig);\n        raw.extend_from_slice(&exp.to_be_bytes());\n        raw.extend_from_slice(user.as_bytes());\n\n        Ok(hex::encode(raw))\n    }\n\n    fn verify_token<'a>(&'a self, token: &str, path: &str) -> Result<(String, &'a AccessPaths)> {\n        let raw = hex::decode(token)?;\n\n        if raw.len() < 72 {\n            bail!(\"Invalid token\");","sourceCodeStart":148,"sourceCodeEnd":184,"githubUrl":"https://github.com/sigoden/dufs/blob/fe7fd564f80dfbac361c8e0589c3845638149d38/src/auth.rs#L148-L184","documentation":"`generate_token` looks up the requested user in the configured `users` map to obtain the password used to derive the signing key. If the user was never configured (no `user:pass@paths` entry in Auth::new), token generation fails with 'Not found user'. The user name is echoed in the message.","triggerScenarios":"Calling `auth.generate_token(path, user)` with a user name absent from the server's auth configuration, including case/whitespace mismatches.","commonSituations":"Typo in the username when minting download/share links; renaming a user in `--auth` but stale code/URLs still referencing the old name; requesting tokens for anonymous access which is not a user.","solutions":["Use a username exactly as configured in the `--auth user:pass@paths` entries.","List/verify configured users before generating tokens.","Fix any case or whitespace differences in the user name.","If anonymous access is needed, use the anonymous paths mechanism rather than generate_token."],"exampleFix":"// before\nlet token = auth.generate_token(\"/\", \"Alice\")?; // configured as alice\n// after\nlet token = auth.generate_token(\"/\", \"alice\")?;","handlingStrategy":"validation","validationCode":"fn user_configured(users: &[String], user: &str) -> bool { users.iter().any(|u| u == user) }\nassert!(user_configured(&configured_users, \"alice\"), \"user not in --auth config\");","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Keep a canonical list of configured usernames","Match case exactly when generating tokens","Update token-minting code when --auth users change","Never mint tokens for the anonymous entry"],"tags":["rust","authentication","user-not-found"],"backgroundTag":"user-not-found","analyzedSha":"fe7fd564f80dfbac361c8e0589c3845638149d38","analyzedAt":"2026-09-09T13:01:22.843Z","contentChangedAt":"2026-09-09T13:01:22.843Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}