receiveMessage method

Message? receiveMessage(
  1. Message msg
)

Implementation

Message? receiveMessage(Message msg) {
  if (_state == stateWelcomeSent) {
    throw ArgumentError("session was established, not expecting any new messages");
  }

  if (msg is Hello) {
    if (_state != stateNone) {
      throw Exception("unknown state");
    }

    String method = anonymous;
    if (msg.authMethods.isNotEmpty) {
      method = msg.authMethods[0];
    }

    _authMethod = method;
    _hello = msg;

    switch (method) {
      case anonymous:
        Request request = Request(method, msg.realm, msg.authID, msg.authExtra);
        Response response = _authenticator.authenticate(request);
        _state = stateWelcomeSent;

        Welcome welcome = Welcome(_sessionID, routerRoles, response.authID, response.authRole, method, authExtra: {});
        _sessionDetails = SessionDetails(_sessionID, msg.realm, welcome.authID, welcome.authRole);

        return welcome;

      case cryptosign:
        if (!msg.authExtra.containsKey("pubkey")) {
          throw Exception("authextra must contain pubkey for $cryptosign");
        }

        String publicKey = msg.authExtra["pubkey"];
        CryptoSignRequest request = CryptoSignRequest(msg.realm, msg.authID, msg.authExtra, publicKey);
        _response = _authenticator.authenticate(request);
        _publicKey = publicKey;

        String challenge = generateCryptoSignChallenge();
        _state = stateChallengeSent;

        return Challenge(method, {"challenge": challenge});

      case wampcra:
        Request request = Request(method, msg.realm, msg.authID, msg.authExtra);
        Response response = _authenticator.authenticate(request);
        if (response is! WAMPCRAResponse) {
          throw Exception("invalid response type for WAMPCRA");
        }

        _response = response;
        _secret = response.secret;

        String challenge = generateWampCRAChallenge(_sessionID, _response.authID, _response.authRole, "dynamic");
        _state = stateChallengeSent;
        _challenge = challenge;

        return Challenge(method, {"challenge": challenge});

      case ticket:
        _state = stateChallengeSent;

        return Challenge(method, {});

      default:
        throw Exception("unknown method");
    }
  } else if (msg is Authenticate) {
    if (_state != stateChallengeSent) {
      throw Exception("unknown state");
    }

    switch (_authMethod) {
      case cryptosign:
        verifyCryptoSignSignature(msg.signature, Base16Encoder.instance.decode(_publicKey));
        _state = stateWelcomeSent;

        Welcome welcome =
            Welcome(_sessionID, routerRoles, _response.authID, _response.authRole, cryptosign, authExtra: {});
        _sessionDetails = SessionDetails(welcome.sessionID, _hello.realm, welcome.authID, welcome.authRole);

        return welcome;

      case wampcra:
        verifyWampCRASignature(msg.signature, _challenge, Uint8List.fromList(_secret.codeUnits));
        _state = stateWelcomeSent;

        Welcome welcome =
            Welcome(_sessionID, routerRoles, _response.authID, _response.authRole, wampcra, authExtra: {});
        _sessionDetails = SessionDetails(welcome.sessionID, _hello.realm, welcome.authID, welcome.authRole);

        return welcome;

      case ticket:
        TicketRequest request = TicketRequest(_hello.realm, _hello.authID, _hello.authExtra, msg.signature);
        Response response = _authenticator.authenticate(request);
        _state = stateWelcomeSent;

        Welcome welcome = Welcome(_sessionID, routerRoles, response.authID, response.authRole, ticket, authExtra: {});
        _sessionDetails = SessionDetails(welcome.sessionID, _hello.realm, welcome.authID, welcome.authRole);

        return welcome;
    }
  } else if (msg is Abort) {
    _state = stateErrored;

    return null;
  } else {
    throw Exception("unknown message");
  }

  return null;
}