grpc: provision sets the verifier on an already-existing account
All checks were successful
CI / check (push) Successful in 3m50s
All checks were successful
CI / check (push) Successful in 3m50s
An Anope import creates accounts (channel ownership, vhosts, certs) but can't carry the one-way password hash, so they exist without a verifier. provision then refused them as AlreadyExists, so the website's backfill could never give migrated members a credential — every one was locked out of password login. Make provision update the verifier in place on an existing account (logged as AccountPasswordSet), and treat an empty scram512 as absent consistently in apply(). Keyed by name, so imported channel/vhost/ban data stays attached.
This commit is contained in:
parent
d1685f7e53
commit
34bc7d69f0
5 changed files with 54 additions and 7 deletions
|
|
@ -42,12 +42,28 @@ impl Db {
|
|||
/// can't clobber a fully-credentialed account). `scram512` empty =
|
||||
/// SCRAM-SHA-512 unavailable for this account (it falls back to 256).
|
||||
pub fn provision_account(&mut self, name: &str, scram256: &str, scram512: &str, email: Option<String>) -> Result<(), RegError> {
|
||||
if self.exists(name) {
|
||||
return Err(RegError::Exists);
|
||||
}
|
||||
if name.is_empty() || scram256.is_empty() {
|
||||
return Err(RegError::Internal);
|
||||
}
|
||||
// The account may already exist without a verifier — an Anope import
|
||||
// creates accounts (channel ownership, vhosts, etc.) but can't carry the
|
||||
// one-way password hash. When the external authority then asserts a
|
||||
// verifier, set it in place rather than refusing, or migrated users could
|
||||
// never log in. Keyed by name, so all imported data stays attached.
|
||||
if self.exists(name) {
|
||||
self.log
|
||||
.append(Event::AccountPasswordSet {
|
||||
account: name.to_string(),
|
||||
scram256: scram256.to_string(),
|
||||
scram512: scram512.to_string(),
|
||||
})
|
||||
.map_err(|_| RegError::Internal)?;
|
||||
if let Some(acct) = self.accounts.get_mut(&key(name)) {
|
||||
acct.scram256 = Some(scram256.to_string());
|
||||
acct.scram512 = (!scram512.is_empty()).then(|| scram512.to_string());
|
||||
}
|
||||
return Ok(());
|
||||
}
|
||||
let account = Account {
|
||||
name: name.to_string(),
|
||||
email,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue