public async void AuthorizeUri()
        {
            var rc = new RestClient(
                Environment.GetEnvironmentVariable("RINGCENTRAL_CLIENT_ID"),
                Environment.GetEnvironmentVariable("RINGCENTRAL_CLIENT_SECRET"),
                Environment.GetEnvironmentVariable("RINGCENTRAL_SERVER_URL")
                );

            var authorizeUriExtension = new AuthorizeUriExtension();

            rc.InstallExtension(authorizeUriExtension);

            var redirectUri = "http://localhost:3000/callback";

            var uri = authorizeUriExtension.BuildUri(new AuthorizeRequest
            {
                redirect_uri = redirectUri,
                state        = "myState"
            });

            Assert.NotNull(uri);
            Assert.Contains("state=myState", uri);

            try
            {
                await rc.Authorize("fakeCode", redirectUri);

                throw new Exception("Code above should throw");
            }
            catch (RestException re)
            {
                Assert.Equal(HttpStatusCode.BadRequest, re.httpResponseMessage.StatusCode);
            }

            var uri2 = authorizeUriExtension.BuildUri(new AuthorizeRequest
            {
                redirect_uri  = redirectUri,
                client_id     = rc.clientId, // optional
                response_type = "code",      // optional
                state         = "hello",
                ui_options    = "hide_logo"
            });

            Assert.NotNull(uri2);
            Assert.Contains("state=hello", uri2);
            Assert.Contains("ui_options=hide_logo", uri2);

            var uri3 = authorizeUriExtension.BuildUri(new AuthorizeRequest
            {
                redirect_uri = redirectUri,
                state        = "hello",
                ui_options   = "hide_logo"
            });

            Assert.NotNull(uri3);
            Assert.Contains("response_type=code", uri3);
            Assert.Contains($"client_id={rc.clientId}", uri3);
        }
        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            app.UseSession();
            app.Run(async(context) =>
            {
                var rc             = new RestClient(RINGCENTRAL_CLIENT_ID, RINGCENTRAL_CLIENT_SECRET, RINGCENTRAL_SERVER_URL);
                var oauthExtension = new AuthorizeUriExtension();
                await rc.InstallExtension(oauthExtension);
                var tokenString = context.Session.GetString(SESSION_TOKEN_KEY);
                if (tokenString != null)
                {
                    rc.token = JsonConvert.DeserializeObject <TokenInfo>(tokenString);
                }
                else if (context.Request.Path != "/oauth2callback")
                {
                    var oauthUri = oauthExtension.BuildUri(
                        new AuthorizeRequest()
                    {
                        redirect_uri = RINGCENTRAL_REDIRECT_URL,
                    });
                    await context.Response.WriteAsync(
                        Html($"<a href=\"{oauthUri}\">Click here to authorize</a>"));
                    return;
                }

                switch (context.Request.Path)
                {
                case "/":
                    await context.Response.WriteAsync(Html(@"<ul>
                                <li><a href=""/test?api=extension"" target=""_blank"">Read Extension Info</a></li>
                                <li><a href=""/test?api=extension-call-log"" target=""_blank"">Read Extension Call Log</a></li>
                                <li><a href=""/test?api=account-call-log"" target=""_blank"">Read Account Call Log</a></li>
                                <li><a href=""/logout"">Logout</a></li>
                            </ul>"));
                    break;

                case "/oauth2callback":
                    context.Request.Query.TryGetValue("code", out var codes);
                    var code = codes.First();
                    await rc.Authorize(code, RINGCENTRAL_REDIRECT_URL);
                    context.Session.SetString(SESSION_TOKEN_KEY, JsonConvert.SerializeObject(rc.token));
                    context.Response.Redirect("/");
                    break;

                case "/test":
                    context.Request.Query.TryGetValue("api", out var apis);
                    var api    = apis.First();
                    var result = "";
                    switch (api)
                    {
                    case "extension":
                        result = await rc.Get <string>("/restapi/v1.0/account/~/extension");
                        break;

                    case "extension-call-log":
                        result = await rc.Get <string>("/restapi/v1.0/account/~/extension/~/call-log");
                        break;

                    case "account-call-log":
                        result = await rc.Get <string>("/restapi/v1.0/account/~/call-log");
                        break;
                    }

                    await context.Response.WriteAsync(Html($"<pre>{result}</pre>"));
                    break;

                case "/logout":
                    await rc.Revoke();
                    context.Session.Remove(SESSION_TOKEN_KEY);
                    context.Response.Redirect("/");
                    break;

                default:
                    context.Response.StatusCode = 404;
                    break;
                }
            });
        }