示例#1
0
        public override Task <IRestResponse> ExecuteTaskAsync(IRestRequest request)
        {
            Task <IRestResponse> authorizeTask = null;

            if (AccessToken == null)
            {
                var authorizationHeader = request.Parameters.FirstOrDefault(x => x.Type == ParameterType.HttpHeader && x.Name == "Authorization");
                if (authorizationHeader != null)
                {
                    AccessToken   = authorizationHeader.Value.ToString().Replace("Bearer ", "");
                    authorizeTask = DoExecuteTaskAsync("authorize", "", AccessToken);
                }
            }
            if (authorizeTask != null)
            {
                return(authorizeTask.ContinueWith <IRestResponse>(authorizeResponse =>
                {
                    if (authorizeResponse.Result.ResponseStatus == ResponseStatus.Completed)
                    {
                        Authorized?.Invoke(this, EventArgs.Empty);
                        var call = DoExecuteTaskAsync(request);
                        call.Wait(request.Timeout - 1);
                        return call.Result;
                    }
                    else
                    {
                        return authorizeResponse.Result;
                    }
                }));
            }
            else
            {
                return(DoExecuteTaskAsync(request));
            }
        }
 BoolValue <AuthResult> onAuthorizationDone(BoolValue <AuthResult> authResult)
 {
     if (authResult)
     {
         Authorized?.Invoke(this, new AuthResultEventArgs(authResult));
     }
     return(authResult);
 }
示例#3
0
        private void HandleSocketMessage(object sender, MessageEventArgs e)
        {
            var message = e.Data;

            try
            {
                var baseMessage = JsonConvert.DeserializeObject <BaseMessage>(message);
                if (baseMessage.Type == SocketMessageTypes.SuccessfullyAuthorized)
                {
                    Authorized?.Invoke();
                }
                else if (baseMessage.Type == SocketMessageTypes.RoomCreated)
                {
                    var response = JsonConvert.DeserializeObject <SocketResponseDTO <RoomDTO> >(message);
                    RoomCreated?.Invoke(response);
                }
                else if (baseMessage.Type == SocketMessageTypes.NewMessage)
                {
                    var response = JsonConvert.DeserializeObject <SocketResponseDTO <MessageDTO> >(message);
                    NewMessageReceived?.Invoke(response);
                }
                else if (baseMessage.Type == SocketMessageTypes.RoomParticipated)
                {
                    var response = JsonConvert.DeserializeObject <SocketResponseDTO <RoomParticipatedDTO> >(message);
                    RoomParticipated?.Invoke(response);
                }
                else if (baseMessage.Type == SocketMessageTypes.RoomLeft)
                {
                    var response = JsonConvert.DeserializeObject <SocketResponseDTO <RoomParticipatedDTO> >(message);
                    RoomLeft?.Invoke(response);
                }
                else if (baseMessage.Type == SocketMessageTypes.FileStatusChanged)
                {
                    var response = JsonConvert.DeserializeObject <SocketResponseDTO <FileStatusDTO> >(message);
                    FileStatusChanged?.Invoke(response);
                }
            }
            catch (Exception ex)
            {
                Failed?.Invoke(ex.Message);
            }
        }
示例#4
0
        public async Task RunAsync(string id)
        {
start:
            if (IsConnected)
            {
                return;
            }
            websocket_cts = new CancellationTokenSource();
            var Authenticator = RacetimeAPI.Instance.Authenticator;

            using (ws = new ClientWebSocket())
            {
                IsConnected = true;

                if (await Authenticator.Authorize())
                {
                    SendSystemMessage($"Authorization successful. Hello, {Authenticator.Identity?.Name}");
                    Authorized?.Invoke(this, null);
                }
                else
                {
                    SendSystemMessage(Authenticator.Error, true);
                    AuthenticationFailed?.Invoke(this, new EventArgs());
                    ConnectionError++;
                    goto cleanup;
                }
                //opening the socket
                ws.Options.SetRequestHeader("Authorization", $"Bearer {Authenticator.AccessToken}");
                try
                {
                    await ws.ConnectAsync(new Uri(FullSocketRoot + "ws/o/race/" + id), websocket_cts.Token);
                }
                catch (WebSocketException wex)
                {
                    ConnectionError++;
                    goto cleanup;
                }

                //initial command to sync LiveSplit
                if (ws.State == WebSocketState.Open)
                {
                    ChannelJoined?.Invoke(this, new EventArgs());
                    SendSystemMessage($"Joined Channel '{id}'");
                    try
                    {
                        ArraySegment <byte> bytesToSend = new ArraySegment <byte>(Encoding.UTF8.GetBytes("{ \"action\":\"getrace\" }"));
                        ws.SendAsync(bytesToSend, WebSocketMessageType.Text, true, CancellationToken.None);
                        await ReceiveAndProcess();

                        if (Race.StartedAt != DateTime.MaxValue)
                        {
                            Model.CurrentState.Run.Offset = DateTime.UtcNow - Race.StartedAt;
                        }
                        else
                        {
                            Model.CurrentState.Run.Offset = -Race.StartDelay;
                        }
                    }
                    catch (Exception ex)
                    {
                        SendSystemMessage("Unable to obtain Race information. Try reloading");
                        //Authenticator.AccessToken = null;
                        //Authenticator.RefreshToken = null;

                        goto cleanup;
                    }
                    try
                    {
                        var rf = new StandardComparisonGeneratorsFactory();

                        if (ConnectionError >= 0) //don't load after every reconnect
                        {
                            SendSystemMessage("Loading chat history...");
                            ArraySegment <byte> otherBytesToSend = new ArraySegment <byte>(Encoding.UTF8.GetBytes("{ \"action\":\"gethistory\" }"));
                            ws.SendAsync(otherBytesToSend, WebSocketMessageType.Text, true, CancellationToken.None);
                            await ReceiveAndProcess();
                        }
                    }
                    catch
                    {
                        SendSystemMessage("Unable to load chat history");
                    }
                }

                ConnectionError = -1;

                while (ws.State == WebSocketState.Open && !websocket_cts.IsCancellationRequested)
                {
                    try
                    {
                        await ReceiveAndProcess();
                    }
                    catch (Exception ex)
                    {
                    }
                }


                switch (ws.State)
                {
                case WebSocketState.CloseSent:
                case WebSocketState.CloseReceived:
                case WebSocketState.Closed:
                    ConnectionError = -1;
                    break;

                default:
                case WebSocketState.Aborted:
                    if (!websocket_cts.IsCancellationRequested)
                    {
                        ConnectionError++;
                    }

                    break;
                }
            }

cleanup:
            IsConnected = false;

            if (ConnectionError >= 0)
            {
                SendSystemMessage($"Auto-reconnect in {reconnectDelays[Math.Min(reconnectDelays.Length-1,ConnectionError)]}s...");
                await Task.Delay(reconnectDelays[Math.Min(reconnectDelays.Length - 1, ConnectionError)] * 1000);

                goto start;
            }
            else
            {
                SendSystemMessage("Disconnect");
            }

            websocket_cts.Dispose();

            Disconnected?.Invoke(this, new EventArgs());
        }
 protected virtual void OnAuthorized(TwainCloudAuthorizedEventArgs e)
 {
     Authorized?.Invoke(this, e);
 }
        public async Task <Guid> RetrieveAccessTokenAsync(OperationContext context, Guid flowId)
        {
            var session = context.OpenSystemSession();
            var flow    = session.GetEntity <IOAuthClientFlow>(flowId);

            Util.Check(flow != null, "OAuth client flow not found, ID: {0}", flowId);
            ThrowIfExpired(flow);
            string err = null;

            switch (flow.Status)
            {
            case OAuthFlowStatus.Started: err = "Access not authorized yet."; break;

            case OAuthFlowStatus.TokenRetrieved: err = "Authorization code already used to retrieve token."; break;

            case OAuthFlowStatus.Error: err = "Authorization failed or denied - " + flow.Error; break;
            }
            Util.Check(err == null, "Cannot retrieve token: {0}.", err);
            Util.CheckNotEmpty(flow.AuthorizationCode, "Authorization code not retrieved, cannot retrieve access token.");

            var apiClient     = new WebApiClient(context, flow.Account.Server.TokenRequestUrl, ClientOptions.Default, badRequestContentType: typeof(string));
            var clientSecret  = flow.Account.ClientSecret;
            var server        = flow.Account.Server;
            var serverOptions = server.Options;
            // Some servers expect clientId/secret in Authorization header
            string query;

            if (serverOptions.IsSet(OAuthServerOptions.ClientInfoInAuthHeader))
            {
                AddClientInfoHeader(apiClient, flow.Account.ClientIdentifier, clientSecret);
                query = StringHelper.FormatUri(AccessTokenUrlQueryTemplate, flow.AuthorizationCode, flow.RedirectUrl);
            }
            else
            {
                //others - clientId/secret mixed with other parameters
                query = StringHelper.FormatUri(AccessTokenUrlQueryTemplateWithClientInfo, flow.AuthorizationCode,
                                               flow.RedirectUrl, flow.Account.ClientIdentifier, clientSecret);
            }

            query = StringHelper.FormatUri(AccessTokenUrlQueryTemplateWithClientInfo, flow.AuthorizationCode,
                                           flow.RedirectUrl, flow.Account.ClientIdentifier, clientSecret);


            //Make a call; standard is POST, but some servers use GET (LinkedIn)
            AccessTokenResponse tokenResp;

            if (serverOptions.IsSet(OAuthServerOptions.TokenUseGet))
            {
                //GET, no body
                tokenResp = await apiClient.GetAsync <AccessTokenResponse>("?" + query);
            }
            else
            {
                var formContent = CreateFormUrlEncodedContent(query);
                tokenResp = await apiClient.PostAsync <HttpContent, AccessTokenResponse>(formContent, string.Empty);
            }
            flow.Status = OAuthFlowStatus.TokenRetrieved;
            //LinkedIn returns milliseconds here - it's a bug, reported. So here is workaround
            var expIn = tokenResp.ExpiresIn;

            if (expIn > 1e+9) //if more than one billion, it is milliseconds
            {
                expIn = expIn / 1000;
            }
            var            expires = this.App.TimeService.UtcNow.AddSeconds(expIn);
            OAuthTokenType tokenType;
            var            ok = Enum.TryParse <OAuthTokenType>(tokenResp.TokenType, true, out tokenType); //should be Bearer
            // Create AccessToken entity
            var accessToken = flow.Account.NewOAuthAccessToken(flow.UserId, tokenResp.AccessToken, tokenType,
                                                               tokenResp.RefreshToken, tokenResp.IdToken, flow.Scopes, App.TimeService.UtcNow, expires, Settings.EncryptionChannel);

            // Unpack OpenId id_token - it is JWT token
            if (serverOptions.IsSet(OAuthServerOptions.OpenIdConnect) && !string.IsNullOrWhiteSpace(tokenResp.IdToken))
            {
                var payload = OpenIdConnectUtil.GetJwtPayload(tokenResp.IdToken);
                var idTkn   = Settings.JsonDeserializer.Deserialize <OpenIdToken>(payload);
                accessToken.NewOpenIdToken(idTkn, payload);
            }
            session.SaveChanges();
            Authorized?.Invoke(this, new OAuthClient.OAuthEventArgs(context, flow.Id));
            return(accessToken.Id);
        }