private static void DoCallHome(object state) { HttpWebClient client = new HttpWebClient(); log.Info("Calling home to " + FileHandlerFactoryLocator.CallHomeEndpoint); client.BeginPost( FileHandlerFactoryLocator.CallHomeEndpoint, delegate(HttpResponseHandler response) { log.Info("Successfully called home to " + FileHandlerFactoryLocator.CallHomeEndpoint); }, delegate(Exception e) { log.Error("Exception when calling home to " + FileHandlerFactoryLocator.CallHomeEndpoint, e); // no-op for strict compiler if (null == Timer) {} }, new KeyValuePair<string, string>("host", FileHandlerFactoryLocator.Hostname)); }
/// <summary> /// Establishes trust between a user and another server /// </summary> /// <param name="sender"></param> /// <param name="receiveNotificationEndpoint"></param> /// <param name="callback"></param> private void BeginEstablishTrust( IUserOrGroup sender, string receiveNotificationEndpoint, string establishTrustEndpoint, Action<string> callback, Action<Exception> errorCallback) { // Make sure the timer is created if (null == EstablishTrustDataTimer) { Timer timer = new Timer(EstablishTrustDataCleanup, null, 600000, 600000); if (null != Interlocked.CompareExchange<Timer>(ref EstablishTrustDataTimer, timer, null)) timer.Dispose(); } // Get the avatar byte[] avatar; ISession session = FileHandlerFactoryLocator.SessionManagerHandler.CreateSession(); try { IWebConnection webConnection = new BlockingShellWebConnection( FileHandlerFactoryLocator.WebServer, session, "/Users/" + sender.Name + ".user?Method=GetAvatar", null, null, null, CallingFrom.Web, WebMethod.GET); IWebResults webResults = webConnection.ShellTo("/Users/" + sender.Name + ".user?Method=GetAvatar"); using (Stream stream = webResults.ResultsAsStream) { avatar = new byte[stream.Length]; stream.Read(avatar, 0, avatar.Length); } } finally { FileHandlerFactoryLocator.SessionManagerHandler.EndSession(session.SessionId); } // Hold on to callback information for use after trust is established string token; using (TimedLock.Lock(EstablishTrustDatasByToken)) { do token = Convert.ToBase64String(SRandom.NextBytes(100)); while (EstablishTrustDatasByToken.ContainsKey(token)); EstablishTrustDatasByToken[token] = new EstablishTrustData(); } HttpWebClient httpWebClient = new HttpWebClient(); httpWebClient.BeginPost( establishTrustEndpoint, delegate(HttpResponseHandler httpResponseHandler) { if (httpResponseHandler.StatusCode == System.Net.HttpStatusCode.Created) { string senderToken; using (TimedLock.Lock(EstablishTrustDatasByToken)) { senderToken = EstablishTrustDatasByToken[token].SenderToken; EstablishTrustDatasByToken.Remove(token); } this.persistedUserManagerData.Write(userManagerData => { var user = userManagerData.GetUser(sender.Id); string oldSenderToken; if (user.receiveNotificationSenderTokensByEndpoint.TryGetValue(receiveNotificationEndpoint, out oldSenderToken)) user.receiveNotificationEndpointsBySenderToken.Remove(oldSenderToken); user.receiveNotificationEndpointsBySenderToken[senderToken] = receiveNotificationEndpoint; user.receiveNotificationSenderTokensByEndpoint[receiveNotificationEndpoint] = senderToken; }); callback(senderToken); } else errorCallback(new ParticleException.CouldNotEstablishTrust("Couldn't establish trust: " + httpResponseHandler.AsString())); }, errorCallback, new KeyValuePair<string, string>("senderIdentity", sender.Identity), new KeyValuePair<string, string>("token", token), new KeyValuePair<string, string>("avatar", Convert.ToBase64String(avatar)), new KeyValuePair<string, string>("loginURL", string.Format("http://{0}/Users/UserDB?Method=OpenIDLogin", FileHandlerFactoryLocator.HostnameAndPort)), new KeyValuePair<string, string>("loginURLOpenID", "openid_url"), new KeyValuePair<string, string>("loginURLWebFinger", "openid_url"), new KeyValuePair<string, string>("loginURLRedirect", "redirect"), GenerateSecurityTimestamp()); }
public IWebResults UserConfirmLink( IWebConnection webConnection, string objectUrl, string ownerIdentity, string linkSummaryView, string linkUrl, string linkDocumentType, string[] recipients, string redirectUrl, string linkID, string password, string remember) { IUser user; if (ownerIdentity != webConnection.Session.User.Identity) { string name = GetLocalUserNameFromOpenID(ownerIdentity); // Load the user and verify the password user = LoadUserAndVerifyPassword(webConnection, name, password); } else user = webConnection.Session.User; Uri domainUri = new Uri(objectUrl); webConnection.Session.User.UserHandler.SetRememberOpenIDLink(domainUri.Host, remember != null); FileHandler.GetEndpointInfos( user, false, recipients, ParticleEndpoint.ConfirmLink, delegate(EndpointInfo endpointInfo) { HttpWebClient httpWebClient = new HttpWebClient(); httpWebClient.BeginPost( endpointInfo.Endpoint, delegate(HttpResponseHandler httpResponseHandler) { }, delegate(Exception e) { log.Warn("Exception calling particle.confirmLink for " + StringGenerator.GenerateCommaSeperatedList(endpointInfo.RecipientIdentities), e); }, new KeyValuePair<string, string>("objectUrl", objectUrl), new KeyValuePair<string, string>("senderToken", endpointInfo.SenderToken), new KeyValuePair<string, string>("linkSummaryView", linkSummaryView), new KeyValuePair<string, string>("linkUrl", linkUrl), new KeyValuePair<string, string>("linkDocumentType", linkDocumentType), new KeyValuePair<string, string>("linkID", linkID), new KeyValuePair<string, string>("recipients", JsonWriter.Serialize(endpointInfo.RecipientIdentities)), GenerateSecurityTimestamp()); }, delegate(IEnumerable<string> recipientsInError) { log.Warn("Could not get particle.confirmLink for the following recipients: " + StringGenerator.GenerateCommaSeperatedList(recipientsInError)); }, delegate(Exception e) { log.Error("Exception getting recipient information for particle.confirmLink", e); }); return WebResults.Redirect(redirectUrl); }
public void SendNotification( IUser sender, EndpointInfo recipientInfo, string objectUrl, string summaryView, string documentType, string verb, string changeData, int maxRetries, TimeSpan transportErrorDelay) { HttpWebClient webClient = new HttpWebClient(); Action retry = delegate() { if (maxRetries > 0) ThreadPool.QueueUserWorkItem(delegate(object state) { Thread.Sleep(transportErrorDelay); SendNotification( sender, recipientInfo, objectUrl, summaryView, documentType, verb, changeData, maxRetries - 1, transportErrorDelay); }); }; webClient.BeginPost( recipientInfo.Endpoint, delegate(HttpResponseHandler response) { string responseString = response.AsString(); if (response.StatusCode == System.Net.HttpStatusCode.OK) // success! { } else if (response.StatusCode == System.Net.HttpStatusCode.Accepted) // errors log.Warn("Errors occured when sending a notification: " + responseString); else if (response.StatusCode == System.Net.HttpStatusCode.PreconditionFailed && "senderToken" == responseString) { SendNotification( sender, true, recipientInfo.RecipientIdentities, objectUrl, summaryView, documentType, verb, changeData, maxRetries, transportErrorDelay); } else retry(); }, delegate(Exception e) { }, new KeyValuePair<string, string>("senderToken", recipientInfo.SenderToken), new KeyValuePair<string, string>("recipients", JsonWriter.Serialize(recipientInfo.RecipientIdentities)), new KeyValuePair<string, string>("objectUrl", objectUrl), new KeyValuePair<string, string>("summaryView", summaryView), new KeyValuePair<string, string>("documentType", documentType), new KeyValuePair<string, string>("verb", verb), new KeyValuePair<string, string>("changeData", changeData), GenerateSecurityTimestamp()); }
public IWebResults EstablishTrust( IWebConnection webConnection, string senderIdentity, string avatar, string token, string loginURL, string loginURLOpenID, string loginURLWebFinger, string loginURLRedirect) { VerifySecurityTimestamp(webConnection); // Decode the avatar, verifying that it's legitimate base64 encoded byte[] avatarBytes; try { avatarBytes = Convert.FromBase64String(avatar); } catch (Exception e) { throw new WebResultsOverrideException(WebResults.From(Status._400_Bad_Request, "Malformed avatar"), e); } // Note: The avatar should be a valid JPEG under 250kb. // For the sake of keeping the network running, this is not verified // Generate a sender token, with a sanity check for duplicates // TODO for the OCD: It's statisically difficult, but this sender token isn't inserted in the database, thus // there's no check against duplicate in-RAM sender tokens string senderToken; bool senderTokenInMemory; string conflictingSenderIdentity; do { // First check the database for a duplicate do senderToken = Convert.ToBase64String(SRandom.NextBytes(100)); while (FileHandler.TryGetSenderIdentity(senderToken, out conflictingSenderIdentity)); // Next check for a duplicate sender token that hasn't yet been written to the DB lock (PendingSenderTokens) { senderTokenInMemory = PendingSenderTokens.Contains(senderToken); if (!senderTokenInMemory) PendingSenderTokens.Add(senderToken); } } while (senderTokenInMemory); Action<HttpResponseHandler> callback = delegate(HttpResponseHandler response) { if (response.StatusCode == System.Net.HttpStatusCode.Accepted) { FileHandler.EstablishTrust(senderIdentity, senderToken, loginURL, loginURLOpenID, loginURLWebFinger, loginURLRedirect); webConnection.SendResults(WebResults.From(Status._201_Created, "created")); IUser senderUser = FileHandlerFactoryLocator.IdentityProviders[1].GetOrCreateUser(senderIdentity); string avatarFilename = senderUser.Id.ToString() + ".jpg"; IBinaryHandler avatarHandler; if (ParticleAvatarsDirectory.IsFilePresent(avatarFilename)) avatarHandler = ParticleAvatarsDirectory.OpenFile(avatarFilename).CastFileHandler<IBinaryHandler>(); else avatarHandler = (IBinaryHandler)ParticleAvatarsDirectory.CreateFile(avatarFilename, "image", null); avatarHandler.WriteAll(avatarBytes); // Remove the sender token from the list of pending sender tokens lock (PendingSenderTokens) PendingSenderTokens.Remove(senderToken); } else webConnection.SendResults(WebResults.From(Status._400_Bad_Request, "Error from RespondTrust")); }; Action<Exception> errorCallback = delegate(Exception e) { webConnection.SendResults(WebResults.From(Status._401_Unauthorized, "Could not establish trust")); }; FileHandler.GetEndpoints( senderIdentity, delegate(IEndpoints endpoints) { HttpWebClient httpWebClient = new HttpWebClient(); httpWebClient.BeginPost( endpoints[ParticleEndpoint.RespondTrust], callback, errorCallback, new KeyValuePair<string, string>("token", token), new KeyValuePair<string, string>("senderToken", senderToken), GenerateSecurityTimestamp()); }, delegate(Exception e) { log.Error("Can not get the endpoint to respond establishing trust from within a call to EstablishTrust", e); }); return null; }