public AuthModule(ITwitterAuthenticatedClient twitterApi, ITwitterUserTracker userTracker)
            : base("/auth")
        {
            this.Get["/signin", true] = async(_, __) =>
            {
                var callbackurl = new UriBuilder(
                    Request.Url.Scheme,
                    Request.Url.HostName,
                    Request.Url.Port ?? 80,
                    "/auth/callback");

                ViewBag.AuthUrl = await twitterApi.GetAuthorizationUri(callbackurl.ToString());

                return(View["SignIn"]);
            };

            this.Get["/callback", true] = async(_, __) =>
            {
                await twitterApi.Authenticate((string)Request.Query.oauth_token, (string)Request.Query.oauth_verifier);

                Guid sessionId = Guid.NewGuid();
                userTracker.Register(sessionId, twitterApi);

                return(this.LoginAndRedirect(sessionId));
            };
        }
        private async Task Authenticate(ITwitterAuthenticatedClient client)
        {
            // shared mutable state - won't be able to run tests in parallel
            HorribleOAuthHacks.Reset();
            var uri = await client.GetAuthorizationUri(string.Concat(OAuthInterceptorUri, "/", HorribleOAuthHacks.OAuthCallBack));

            //requires user interaction to authorize the app - brittle
            Process.Start(uri.ToString());

            //wait until the user has completed the oauth flow - might time out or hang
            await Wait.Until(() => HorribleOAuthHacks.IsOAuthSigninCompleted);

            //authenticate the service
            await client.Authenticate(HorribleOAuthHacks.OAuthToken, HorribleOAuthHacks.OAuthVerifier);
        }