authenticate method
Runs the in-band handshake over connection for the upgrade request.
Implementation
@override
Future<omnyhub.Principal?> authenticate(
omnyhub.HandshakeConnection connection,
omnyhub.HubRequest request,
) async {
final channel = HandshakeChannel(connection);
final hello = await channel.expect<Hello>(timeout: timeout);
if (!ProtocolVersion.current.isCompatibleWith(
ProtocolVersion.parse(hello.protocolVersion),
)) {
// Report before rejecting: a peer that cannot parse our protocol still
// needs to learn *why* it was turned away.
channel.send(
const ProtocolErrorMessage(
code: ErrorCodes.versionMismatch,
message: 'incompatible protocol version',
),
);
throw const omnyhub.UnauthorizedException(
'incompatible protocol version',
);
}
final challenge = challenges.next();
channel.send(AuthChallenge(encodeChallenge(challenge)));
final submit = await channel.expect<AuthSubmit>(timeout: timeout);
try {
final principal = await authenticator.authenticate(
submit.credential,
challenge: challenge,
);
channel.send(
AuthOk(
principalId: principal.id.value,
roles: principal.roles.toList(),
),
);
// Carry the roles across the boundary so the gateway's registration
// handler can authorize on them without re-reading the credential.
return omnyhub.Principal(id: principal.id.value, roles: principal.roles);
} on AuthException catch (e) {
channel.send(AuthFail(e.message));
await onRejected?.call(submit.credential.principal, e.message);
throw omnyhub.UnauthorizedException(e.message);
}
}