onHello method

  1. @override
Future<AuthResult> onHello(
  1. AuthenticatorContext context
)
override

Handles the HELLO frame and returns a result.

Implementation

@override
Future<AuthResult> onHello(AuthenticatorContext context) async {
  final authId = _extractAuthId(context.helloDetails);
  final rateLimitFailure = _guardRateLimit(authId);
  if (rateLimitFailure != null) {
    return AuthResult.failure(rateLimitFailure);
  }
  final transactionId = _generateTransactionId();
  final issuedAt = DateTime.now();
  final selected = await _invokeHello(
    context: context,
    transactionId: transactionId,
    issuedAt: issuedAt,
  );
  if (selected == null) {
    return AuthResult.failure(
      const AuthFailure(
        reason: wamp_core.Error.notAuthorized,
        message: 'Remote authentication service unavailable',
      ),
    );
  }
  final (handle, rawResponse) = selected;
  try {
    switch (rawResponse.status) {
      case RemoteHelloStatus.success:
        final success = _sanitizeSuccess(rawResponse.success!);
        final failure = _validateSuccess(success);
        if (failure != null) {
          _registerFailure(authId);
          return AuthResult.failure(failure);
        }
        _registerSuccess(authId);
        handle.markSuccess();
        return AuthResult.success(success);
      case RemoteHelloStatus.failure:
        final failure = _sanitizeFailure(rawResponse.failure!);
        _registerFailure(authId);
        handle.markSuccess();
        if (_config.fakeChallengeOnHelloFailure) {
          _pending = _RemotePendingSession(
            authId: authId ?? 'unknown',
            sessionId: context.sessionId,
            transactionId: transactionId,
            issuedAt: issuedAt,
            delegateId: handle.id,
            shouldFail: true,
            failure: AuthFailure(
              reason: wamp_core.Error.authenticationFailed,
              message: failure.message,
              details: failure.details,
              arguments: failure.arguments,
              argumentsKeywords: failure.argumentsKeywords,
            ),
          );
          return AuthResult.challenge(
            AuthChallenge(
              challenge: _fakeChallenge(
                context: context,
                authId: authId ?? 'unknown',
              ),
              extra: const {'fake': true},
            ),
          );
        }
        return AuthResult.failure(failure);
      case RemoteHelloStatus.challenge:
        final challenge = _sanitizeChallenge(rawResponse.challenge!);
        _pending = _RemotePendingSession(
          authId: challenge.authId,
          sessionId: context.sessionId,
          transactionId: transactionId,
          issuedAt: issuedAt,
          delegateId: handle.id,
        );
        handle.markSuccess();
        return AuthResult.challenge(
          AuthChallenge(
            challenge: challenge.challenge,
            extra: challenge.extra,
          ),
        );
    }
  } on _RemoteSchemaException catch (error) {
    _registerFailure(authId);
    handle.markSuccess();
    return AuthResult.failure(
      AuthFailure(
        reason: wamp_core.Error.notAuthorized,
        message: error.message,
      ),
    );
  }
}