authorize method Null safety

  1. @Operation()
Future<Response> authorize(
  1. {@Bind("username") String? username,
  2. @Bind("password") String? password,
  3. @Bind("scope") String? scope}
)

Creates a one-time use authorization code or an access token.

This method will respond with a redirect that either contains an authorization code ('code') or an access token ('token') along with the passed in 'state'. If this request fails, the redirect URL will contain an 'error' instead of the authorization code or access token.

This method is typically invoked by the login form returned from the GET to this controller.

Implementation

@Operation.post()
Future<Response> authorize({
  /// The username of the authenticating user.
  @Bind.query("username") String? username,

  /// The password of the authenticating user.
  @Bind.query("password") String? password,

  /// A space-delimited list of access scopes being requested.
  @Bind.query("scope") String? scope,
}) async {
  final client = await authServer!.getClient(clientID);

  if (client?.redirectURI == null) {
    return Response.badRequest();
  }

  if (responseType == "token" && !allowsImplicit) {
    return _unsupportedResponseTypeResponse;
  }

  if (state == null) {
    return _redirectResponse(
      null,
      null,
      error: AuthServerException(AuthRequestError.invalidRequest, client),
    );
  }

  try {
    final scopes = scope?.split(" ").map((s) => AuthScope(s)).toList();

    if (responseType == "code") {
      if (client!.hashedSecret == null) {
        return _redirectResponse(
          null,
          state,
          error: AuthServerException(
            AuthRequestError.unauthorizedClient,
            client,
          ),
        );
      }

      final authCode = await authServer!.authenticateForCode(
        username,
        password,
        clientID,
        requestedScopes: scopes,
      );
      return _redirectResponse(
        client.redirectURI,
        state,
        code: authCode.code,
      );
    } else if (responseType == "token") {
      final token = await authServer!.authenticate(
        username,
        password,
        clientID,
        null,
        requestedScopes: scopes,
      );
      return _redirectResponse(client!.redirectURI, state, token: token);
    } else {
      return _redirectResponse(
        null,
        state,
        error: AuthServerException(AuthRequestError.invalidRequest, client),
      );
    }
  } on FormatException {
    return _redirectResponse(
      null,
      state,
      error: AuthServerException(AuthRequestError.invalidScope, client),
    );
  } on AuthServerException catch (e) {
    if (responseType == "token" &&
        e.reason == AuthRequestError.invalidGrant) {
      return _redirectResponse(
        null,
        state,
        error: AuthServerException(AuthRequestError.accessDenied, client),
      );
    }

    return _redirectResponse(null, state, error: e);
  }
}