public IInternalSession Create(string swid) { byte[] localStorageKey = keychain.LocalStorageKey; IDocumentCollection <AlertDocument> documentCollection = GetDocumentCollection <AlertDocument>(swid, "Alerts", databaseDirectoryCreator, localStorageKey, documentCollectionFactory); IDocumentCollection <FriendDocument> documentCollection2 = GetDocumentCollection <FriendDocument>(swid, "Friends", databaseDirectoryCreator, localStorageKey, documentCollectionFactory); IDocumentCollection <FriendInvitationDocument> documentCollection3 = GetDocumentCollection <FriendInvitationDocument>(swid, "FriendInvitations", databaseDirectoryCreator, localStorageKey, documentCollectionFactory); IDocumentCollection <UserDocument> documentCollection4 = GetDocumentCollection <UserDocument>(swid, "Users", databaseDirectoryCreator, localStorageKey, documentCollectionFactory); databaseCorruptionHandler.Add(documentCollection4); string dirPath = BuildDocCollectionPath(databaseDirectoryCreator, swid); UserDatabase userDatabase = new UserDatabase(documentCollection, documentCollection2, documentCollection3, documentCollection4, localStorageKey, dirPath, epochTime, documentCollectionFactory, databaseCorruptionHandler, coroutineManager); database.ClearServerTimeOffsetMillis(); epochTime.OffsetMilliseconds = database.GetServerTimeOffsetMillis() ?? 0; logger.Debug("Initial time offset: " + epochTime.Offset); SessionDocument sessionDocument = database.GetSessionDocument(swid); keychain.PushNotificationKey = sessionDocument.CurrentSymmetricEncryptionKey; IWebCallEncryptor webCallEncryptor = webCallEncryptorFactory.Create(sessionDocument.CurrentSymmetricEncryptionKey, sessionDocument.SessionId); IGuestControllerClient guestControllerClient = guestControllerClientFactory.Create(swid); ISessionRefresher sessionRefresher = sessionRefresherFactory.Create(mixSessionStarter, guestControllerClient); IMixWebCallFactory mixWebCallFactory = mixWebCallFactoryFactory.Create(webCallEncryptor, swid, sessionDocument.GuestControllerAccessToken, sessionRefresher); guestControllerClient.OnAccessTokenChanged += delegate(object sender, AbstractGuestControllerAccessTokenChangedEventArgs e) { mixWebCallFactory.GuestControllerAccessToken = e.GuestControllerAccessToken; }; AssetLoader assetLoader = new AssetLoader(logger, wwwCallFactory); IList <IInternalFriend> friends = CreateFriends(userDatabase); AgeBandType ageBandType = AgeBandTypeConverter.Convert(sessionDocument.AgeBand); DateTime lastRefreshTime = epochTime.FromSeconds(sessionDocument.LastProfileRefreshTime); RegistrationProfile registrationProfile = new RegistrationProfile(logger, sessionDocument.DisplayNameText, sessionDocument.ProposedDisplayName, sessionDocument.ProposedDisplayNameStatus, sessionDocument.FirstName, sessionDocument.AccountStatus, lastRefreshTime, sessionDocument.CountryCode); GetStateResponseParser getStateResponseParser = new GetStateResponseParser(logger); NotificationPoller notificationPoller = new NotificationPoller(logger, mixWebCallFactory, notificationQueue, pollCountdownStopwatch, getStateResponseParser, epochTime, random, database, swid); DisplayName displayName = new DisplayName(sessionDocument.DisplayNameText); LocalUser localUser = new LocalUser(logger, displayName, swid, friends, ageBandType, database, userDatabase, registrationProfile, mixWebCallFactory, guestControllerClient, notificationQueue, encryptor, epochTime); Session session = new Session(logger, localUser, sessionDocument.GuestControllerAccessToken, sessionDocument.PushNotificationToken != null, notificationPoller, coroutineManager, database, userDatabase, guestControllerClient, mixWebCallFactory, epochTime, databaseCorruptionHandler, sessionStatus, keychain, getStateResponseParser, clientVersion, notificationQueue); try { NotificationHandler.Handle(notificationDispatcher, userDatabase, localUser, epochTime); notificationQueue.LatestSequenceNumber = sessionDocument.LatestNotificationSequenceNumber; IEnumerable <IncomingFriendInvitation> incomingFriendInvitations = GetIncomingFriendInvitations(userDatabase, localUser); foreach (IncomingFriendInvitation item in incomingFriendInvitations) { localUser.AddIncomingFriendInvitation(item); } IEnumerable <OutgoingFriendInvitation> outgoingFriendInvitations = GetOutgoingFriendInvitations(userDatabase, localUser); foreach (OutgoingFriendInvitation item2 in outgoingFriendInvitations) { localUser.AddOutgoingFriendInvitation(item2); } } catch (Exception) { session.Dispose(); throw; } return(session); }
public MixSessionStarter(AbstractLogger logger, IRsaEncryptor rsaEncryptor, IDatabase database, IWebCallEncryptorFactory webCallEncryptorFactory, IWebCallEncryptor sessionStartEncryptor, IMixWebCallFactoryFactory mixWebCallFactoryFactory, IKeychain keychain, ICoroutineManager coroutineManager, ISessionRefresherFactory sessionRefresherFactory) { this.logger = logger; this.rsaEncryptor = rsaEncryptor; this.database = database; this.webCallEncryptorFactory = webCallEncryptorFactory; this.sessionStartEncryptor = sessionStartEncryptor; this.mixWebCallFactoryFactory = mixWebCallFactoryFactory; this.keychain = keychain; this.coroutineManager = coroutineManager; this.sessionRefresherFactory = sessionRefresherFactory; }
public void RefreshSession(string guestControllerAccessToken, string swid, Action <IWebCallEncryptor> successCallback, Action failureCallback) { webCallQueue.HandleRefreshing(); mixSessionStarter.Start(swid, guestControllerAccessToken, delegate(MixSessionStartResult result) { IWebCallEncryptor webCallEncryptor = result.WebCallEncryptor; successCallback(webCallEncryptor); webCallQueue.HandleCombinedRefreshSuccess(guestControllerAccessToken, webCallEncryptor); }, delegate { failureCallback(); webCallQueue.HandleSessionRefreshFailure(); }); }
public MixWebCallFactory(AbstractLogger logger, string host, IWwwCallFactory wwwCallFactory, IWebCallEncryptor webCallEncryptor, string swid, string guestControllerAccessToken, string mixClientToken, IMixWebCallQueue webCallQueue, ISessionRefresher sessionRefresher, IEpochTime epochTime, IDatabase database) { this.logger = logger; this.host = host; this.wwwCallFactory = wwwCallFactory; this.webCallEncryptor = webCallEncryptor; this.swid = swid; this.guestControllerAccessToken = guestControllerAccessToken; this.mixClientToken = mixClientToken; this.webCallQueue = webCallQueue; this.sessionRefresher = sessionRefresher; this.epochTime = epochTime; this.database = database; webCalls = new List <IDisposable>(); }
public MixWebCall(AbstractLogger logger, Uri uri, string body, HttpMethod method, Dictionary <string, string> headers, IWwwCallFactory wwwCallFactory, IWebCallEncryptor webCallEncryptor, long latencyWwwCallTimeout, long maxWwwCallTimeout, IDatabase database, string swid) { this.logger = logger; this.uri = uri; this.body = body; this.method = method; this.headers = headers; this.wwwCallFactory = wwwCallFactory; this.latencyWwwCallTimeout = latencyWwwCallTimeout; this.maxWwwCallTimeout = maxWwwCallTimeout; this.database = database; this.swid = swid; WebCallEncryptor = webCallEncryptor; RefreshStatus = WebCallRefreshStatus.NotRefreshing; timeoutLogs = new StringBuilder(); }
private void Start(string swid, string guestControllerAccessToken, RSAParameters rsaParameters, Action<MixSessionStartResult> successCallback, Action failureCallback) { try { ISessionRefresher sessionRefresher = sessionRefresherFactory.Create(this); IMixWebCallFactory mixWebCallFactory = mixWebCallFactoryFactory.Create(sessionStartEncryptor, swid, guestControllerAccessToken, sessionRefresher); StartUserSessionRequest request = BuildRequest(swid, rsaParameters); IWebCall<StartUserSessionRequest, StartUserSessionResponse> webCall = mixWebCallFactory.SessionUserPut(request); webCall.OnResponse += delegate(object sender, WebCallEventArgs<StartUserSessionResponse> e) { StartUserSessionResponse response = e.Response; if (!ValidateResponse(response)) { logger.Critical("Error parsing the session start response: " + JsonParser.ToJson(response)); failureCallback(); } else { long sessionId = response.SessionId.Value; byte[] ciphertext = Convert.FromBase64String(response.EncryptedSymmetricKey); byte[] symmetricKey = rsaEncryptor.Decrypt(ciphertext, rsaParameters); keychain.PushNotificationKey = symmetricKey; database.UpdateSessionDocument(swid, delegate(SessionDocument doc) { doc.PreviousSymmetricEncryptionKey = doc.CurrentSymmetricEncryptionKey; doc.CurrentSymmetricEncryptionKey = symmetricKey; doc.SessionId = sessionId; doc.LatestNotificationSequenceNumber = 0L; }); IWebCallEncryptor webCallEncryptor = webCallEncryptorFactory.Create(symmetricKey, sessionId); MixSessionStartResult obj = new MixSessionStartResult(webCallEncryptor); successCallback(obj); } }; webCall.OnError += delegate { failureCallback(); }; webCall.Execute(force: true); } catch (Exception ex) { logger.Critical("Unhandled exception: " + ex); failureCallback(); } }
private void HandleOnUnauthorized <TRequest, TResponse>(IWebCall <TRequest, TResponse> webCall, WebCallUnauthorizedEventArgs e) where TRequest : BaseUserRequest where TResponse : BaseResponse, new() { if (webCallEncryptor.SessionId == null) { webCall.DispatchError("Unauthorized access to start a new session!"); } else if (!isSessionRefreshing) { if (webCall.RefreshStatus == WebCallRefreshStatus.RefreshedWhileWaitingForCallback) { webCall.RefreshStatus = WebCallRefreshStatus.NotRefreshing; webCall.Execute(); return; } webCall.RefreshStatus = WebCallRefreshStatus.WaitingForRefreshCallback; isSessionRefreshing = true; switch (e.Status) { case "UNAUTHORIZED_ONEID_TOKEN": sessionRefresher.RefreshGuestControllerToken(swid, delegate { isSessionRefreshing = false; }, delegate { isSessionRefreshing = false; }); break; case "UNAUTHORIZED_MIX_SESSION": sessionRefresher.RefreshSession(guestControllerAccessToken, swid, delegate(IWebCallEncryptor encryptor) { isSessionRefreshing = false; webCallEncryptor = encryptor; }, delegate { isSessionRefreshing = false; this.OnAuthenticationLost(this, new AuthenticationUnavailableEventArgs()); }); break; case "UNAUTHORIZED_BANNED": webCall.DispatchError("Account is banned!"); isSessionRefreshing = false; this.OnAuthenticationLost(this, new AccountBannedEventArgs(logger, e.ResponseText)); break; default: sessionRefresher.RefreshAll(swid, delegate(IWebCallEncryptor encryptor) { isSessionRefreshing = false; webCallEncryptor = encryptor; }, delegate { isSessionRefreshing = false; this.OnAuthenticationLost(this, new AuthenticationUnavailableEventArgs()); }); break; } } else { webCall.RefreshStatus = WebCallRefreshStatus.WaitingForRefreshCallback; } }
public IMixWebCallFactory Create(IWebCallEncryptor webCallEncryptor, string swid, string guestControllerAccessToken, ISessionRefresher sessionRefresher) { return(new MixWebCallFactory(logger, hostUrl, wwwCallFactory, webCallEncryptor, swid, guestControllerAccessToken, mixClientToken, webCallQueue, sessionRefresher, epochTime, database)); }
private static void HandleRefreshCallback <TRequest, TResponse>(IWebCall <TRequest, TResponse> webCall, bool needAuthToken, string authToken, bool needSession, IWebCallEncryptor webCallEncryptor) where TRequest : BaseUserRequest where TResponse : BaseResponse, new() { if (needAuthToken && authToken != null) { webCall.SetHeader("X-Mix-OneIdToken", authToken); } if (needSession && webCallEncryptor != null) { webCall.WebCallEncryptor = webCallEncryptor; webCall.SetHeader("X-Mix-UserSessionId", webCallEncryptor.SessionId); } if (webCall.RefreshStatus == WebCallRefreshStatus.WaitingForRefreshCallback) { webCall.RefreshStatus = WebCallRefreshStatus.NotRefreshing; bool flag = true; if (needAuthToken && authToken == null) { flag = false; webCall.DispatchError("GuestController token expired and couldn't get a new token"); } if (needSession && webCallEncryptor == null) { flag = false; webCall.DispatchError("Session expired and couldn't start a new session"); } if (flag) { webCall.Execute(); } } else { webCall.RefreshStatus = WebCallRefreshStatus.RefreshedWhileWaitingForCallback; } }
private void HandleRefreshResult(bool needAuthToken, string authToken, bool needSession, IWebCallEncryptor webCallEncryptor) { isRefreshing = false; Action <bool, string, bool, IWebCallEncryptor>[] array = queuedWebCalls.Values.ToArray(); foreach (KeyValuePair <object, Action <bool, string, bool, IWebCallEncryptor> > queuedWebCall in queuedWebCalls) { webCalls[queuedWebCall.Key] = queuedWebCall.Value; } queuedWebCalls.Clear(); Action <bool, string, bool, IWebCallEncryptor>[] array2 = array; foreach (Action <bool, string, bool, IWebCallEncryptor> action in array2) { action(needAuthToken, authToken, needSession, webCallEncryptor); } }
public void HandleCombinedRefreshSuccess(string guestControllerAccessToken, IWebCallEncryptor encryptor) { HandleRefreshResult(needAuthToken: true, guestControllerAccessToken, needSession: true, encryptor); }
public void HandleSessionRefreshSuccess(IWebCallEncryptor encryptor) { HandleRefreshResult(needAuthToken: false, null, needSession: true, encryptor); }
public MixSessionStartResult(IWebCallEncryptor webCallEncryptor) { WebCallEncryptor = webCallEncryptor; }