public void TestFacebookAuthorizer() { const string token = "pyrzqxgl"; var site = new Uri("https://example.com/database"); const string email = "*****@*****.**"; // Register and retrieve the sample token: var auth = new FacebookAuthorizer(email); Assert.IsTrue(FacebookAuthorizer.RegisterAccessToken(token, email, site)); var gotToken = auth.TokenForSite(site); Assert.AreEqual(token, gotToken); // Register and retrieve the sample token: gotToken = auth.TokenForSite(new Uri("HttpS://example.com:443/some/other/path")); Assert.AreEqual(token, gotToken); Assert.AreEqual(new Dictionary<string, string> { { "access_token", token } }, auth.LoginParametersForSite(site)); }
public static FacebookAuthorizer FromUri(Uri uri) { var facebookAccessToken = URIUtils.GetQueryParameter(uri, QueryParameter); if (facebookAccessToken != null && !StringEx.IsNullOrWhiteSpace(facebookAccessToken)) { var email = URIUtils.GetQueryParameter(uri, QueryParameterEmail); var authorizer = new FacebookAuthorizer(email); Uri remoteWithQueryRemoved = null; try { remoteWithQueryRemoved = new UriBuilder(uri.Scheme, uri.Host, uri.Port, uri.AbsolutePath).Uri; } catch (UriFormatException e) { throw Misc.CreateExceptionAndLog(Log.To.Sync, e, Tag, "Invalid URI format for remote endpoint"); } RegisterAccessToken(facebookAccessToken, email, remoteWithQueryRemoved); return(authorizer); } return(null); }
/// <summary> /// Default constructor /// </summary> /// <param name="db">The local database to replicate to/from</param> /// <param name="remote">The remote Uri to sync with</param> /// <param name="continuous">If set to <c>true</c> continuous.</param> /// <param name="clientFactory">The client factory for instantiating the HttpClient used to create web requests</param> /// <param name="workExecutor">The TaskFactory to execute work on</param> protected Replication(Database db, Uri remote, bool continuous, IHttpClientFactory clientFactory, TaskFactory workExecutor) { LocalDatabase = db; Continuous = continuous; // NOTE: Consider running a separate scheduler for all http requests. WorkExecutor = workExecutor; CancellationTokenSource = new CancellationTokenSource(); RemoteUrl = remote; RequestHeaders = new Dictionary<String, Object>(); _requests = new ConcurrentDictionary<HttpRequestMessage, Task>(); // FIXME: Refactor to visitor pattern. if (RemoteUrl.GetQuery() != null && !StringEx.IsNullOrWhiteSpace(RemoteUrl.GetQuery())) { var uri = new Uri(remote.ToString()); var personaAssertion = URIUtils.GetQueryParameter(uri, PersonaAuthorizer.QueryParameter); if (personaAssertion != null && !StringEx.IsNullOrWhiteSpace(personaAssertion)) { var email = PersonaAuthorizer.RegisterAssertion(personaAssertion); var authorizer = new PersonaAuthorizer(email); Authenticator = authorizer; } var facebookAccessToken = URIUtils.GetQueryParameter(uri, FacebookAuthorizer.QueryParameter); if (facebookAccessToken != null && !StringEx.IsNullOrWhiteSpace(facebookAccessToken)) { var email = URIUtils.GetQueryParameter(uri, FacebookAuthorizer.QueryParameterEmail); var authorizer = new FacebookAuthorizer(email); Uri remoteWithQueryRemoved = null; try { remoteWithQueryRemoved = new UriBuilder(remote.Scheme, remote.GetHost(), remote.Port, remote.AbsolutePath).Uri; } catch (UriFormatException e) { throw new ArgumentException("Invalid URI format.", "remote", e); } FacebookAuthorizer.RegisterAccessToken(facebookAccessToken, email, remoteWithQueryRemoved.ToString()); Authenticator = authorizer; } // we need to remove the query from the URL, since it will cause problems when // communicating with sync gw / couchdb try { RemoteUrl = new UriBuilder(remote.Scheme, remote.GetHost(), remote.Port, remote.AbsolutePath).Uri; } catch (UriFormatException e) { throw new ArgumentException("Invalid URI format.", "remote", e); } } Batcher = new Batcher<RevisionInternal>(workExecutor, INBOX_CAPACITY, PROCESSOR_DELAY, inbox => { try { Log.V(TAG, "*** BEGIN ProcessInbox ({0} sequences)", inbox.Count); FireTrigger(ReplicationTrigger.Resume); ProcessInbox (new RevisionList(inbox)); Log.V(TAG, "*** END ProcessInbox (lastSequence={0})", LastSequence); } catch (Exception e) { Log.E(TAG, "ProcessInbox failed: ", e); throw new RuntimeException(e); } }); ClientFactory = clientFactory; _stateMachine = new StateMachine<ReplicationState, ReplicationTrigger>(ReplicationState.Initial); InitializeStateMachine(); }
public Replication GetReplicator(IDictionary<string, object> properties) { // TODO: in the iOS equivalent of this code, there is: {@"doc_ids", _documentIDs}) - write unit test that detects this bug // TODO: ditto for "headers" Authorizer authorizer = null; Replication repl = null; Uri remote = null; IDictionary<string, object> remoteMap; IDictionary<string, object> sourceMap = ParseSourceOrTarget(properties, "source"); IDictionary<string, object> targetMap = ParseSourceOrTarget(properties, "target"); string source = (string)sourceMap.Get("url"); string target = (string)targetMap.Get("url"); bool createTargetBoolean = (bool)properties.Get("create_target"); bool createTarget = (createTargetBoolean != null && createTargetBoolean); bool continuousBoolean = (bool)properties.Get("continuous"); bool continuous = (continuousBoolean != null && continuousBoolean); bool cancelBoolean = (bool)properties.Get("cancel"); bool cancel = (cancelBoolean != null && cancelBoolean); // Map the 'source' and 'target' JSON params to a local database and remote URL: if (source == null || target == null) { throw new CouchbaseLiteException("source and target are both null", new Status(Status .BadRequest)); } bool push = false; Database db = null; string remoteStr = null; if (Couchbase.Lite.Manager.IsValidDatabaseName(source)) { db = GetExistingDatabase(source); remoteStr = target; push = true; remoteMap = targetMap; } else { remoteStr = source; if (createTarget && !cancel) { bool mustExist = false; db = GetDatabaseWithoutOpening(target, mustExist); if (!db.Open()) { throw new CouchbaseLiteException("cannot open database: " + db, new Status(Status .InternalServerError)); } } else { db = GetExistingDatabase(target); } if (db == null) { throw new CouchbaseLiteException("database is null", new Status(Status.NotFound)); } remoteMap = sourceMap; } IDictionary<string, object> authMap = (IDictionary<string, object>)remoteMap.Get( "auth"); if (authMap != null) { IDictionary<string, object> persona = (IDictionary<string, object>)authMap.Get("persona" ); if (persona != null) { string email = (string)persona.Get("email"); authorizer = new PersonaAuthorizer(email); } IDictionary<string, object> facebook = (IDictionary<string, object>)authMap.Get("facebook" ); if (facebook != null) { string email = (string)facebook.Get("email"); authorizer = new FacebookAuthorizer(email); } } try { remote = new Uri(remoteStr); } catch (UriFormatException) { throw new CouchbaseLiteException("malformed remote url: " + remoteStr, new Status (Status.BadRequest)); } if (remote == null) { throw new CouchbaseLiteException("remote URL is null: " + remoteStr, new Status(Status .BadRequest)); } if (!cancel) { repl = db.GetReplicator(remote, GetDefaultHttpClientFactory(), push, continuous, GetWorkExecutor()); if (repl == null) { throw new CouchbaseLiteException("unable to create replicator with remote: " + remote , new Status(Status.InternalServerError)); } if (authorizer != null) { repl.SetAuthenticator(authorizer); } IDictionary<string, object> headers = (IDictionary)properties.Get("headers"); if (headers != null && !headers.IsEmpty()) { repl.SetHeaders(headers); } string filterName = (string)properties.Get("filter"); if (filterName != null) { repl.SetFilter(filterName); IDictionary<string, object> filterParams = (IDictionary<string, object>)properties .Get("query_params"); if (filterParams != null) { repl.SetFilterParams(filterParams); } } if (push) { ((Pusher)repl).SetCreateTarget(createTarget); } } else { // Cancel replication: repl = db.GetActiveReplicator(remote, push); if (repl == null) { throw new CouchbaseLiteException("unable to lookup replicator with remote: " + remote , new Status(Status.NotFound)); } } return repl; }
/// <summary>Private Constructor</summary> protected Replication(Database db, Uri remote, bool continuous, IHttpClientFactory clientFactory, TaskFactory workExecutor) { LocalDatabase = db; Continuous = continuous; // NOTE: Consider running a separate scheduler for all http requests. WorkExecutor = workExecutor; CancellationTokenSource = new CancellationTokenSource(); RemoteUrl = remote; Status = ReplicationStatus.Stopped; online = Manager.SharedInstance.NetworkReachabilityManager.CurrentStatus == NetworkReachabilityStatus.Reachable; RequestHeaders = new Dictionary<String, Object>(); requests = new HashSet<HttpClient>(); // FIXME: Refactor to visitor pattern. if (RemoteUrl.GetQuery() != null && !RemoteUrl.GetQuery().IsEmpty()) { var uri = new Uri(remote.ToString()); var personaAssertion = URIUtils.GetQueryParameter(uri, PersonaAuthorizer.QueryParameter); if (personaAssertion != null && !personaAssertion.IsEmpty()) { var email = PersonaAuthorizer.RegisterAssertion(personaAssertion); var authorizer = new PersonaAuthorizer(email); Authenticator = authorizer; } var facebookAccessToken = URIUtils.GetQueryParameter(uri, FacebookAuthorizer.QueryParameter); if (facebookAccessToken != null && !facebookAccessToken.IsEmpty()) { var email = URIUtils.GetQueryParameter(uri, FacebookAuthorizer.QueryParameterEmail); var authorizer = new FacebookAuthorizer(email); Uri remoteWithQueryRemoved = null; try { remoteWithQueryRemoved = new UriBuilder(remote.Scheme, remote.GetHost(), remote.Port, remote.AbsolutePath).Uri; } catch (UriFormatException e) { throw new ArgumentException("Invalid URI format.", "remote", e); } FacebookAuthorizer.RegisterAccessToken(facebookAccessToken, email, remoteWithQueryRemoved.ToString()); Authenticator = authorizer; } // we need to remove the query from the URL, since it will cause problems when // communicating with sync gw / couchdb try { RemoteUrl = new UriBuilder(remote.Scheme, remote.GetHost(), remote.Port, remote.AbsolutePath).Uri; } catch (UriFormatException e) { throw new ArgumentException("Invalid URI format.", "remote", e); } } Batcher = new Batcher<RevisionInternal>(workExecutor, InboxCapacity, ProcessorDelay, inbox => { try { Log.V(Tag, "*** BEGIN ProcessInbox ({0} sequences)", inbox.Count); ProcessInbox (new RevisionList(inbox)); Log.V(Tag, "*** END ProcessInbox (lastSequence={0})", LastSequence); UpdateActive(); } catch (Exception e) { Log.E(Tag, "ERROR: ProcessInbox failed: ", e); throw new RuntimeException(e); } }); SetClientFactory(clientFactory); }
public static IAuthenticator CreateFromUri(Uri uri) { return((IAuthenticator)FacebookAuthorizer.FromUri(uri) ?? (IAuthenticator)PersonaAuthorizer.FromUri(uri) ?? BasicAuthenticator.FromUri(uri)); }
/// <summary>Private Constructor</summary> protected Replication(Database db, Uri remote, bool continuous, IHttpClientFactory clientFactory, TaskFactory workExecutor, CancellationTokenSource tokenSource = null) { LocalDatabase = db; Continuous = continuous; WorkExecutor = workExecutor; CancellationTokenSource = tokenSource ?? new CancellationTokenSource(); RemoteUrl = remote; Status = ReplicationStatus.Stopped; online = true; RequestHeaders = new Dictionary<String, Object>(); if (RemoteUrl.GetQuery() != null && !RemoteUrl.GetQuery().IsEmpty()) { var uri = new Uri(remote.ToString()); var personaAssertion = URIUtils.GetQueryParameter(uri, PersonaAuthorizer.QueryParameter); if (personaAssertion != null && !personaAssertion.IsEmpty()) { var email = PersonaAuthorizer.RegisterAssertion(personaAssertion); var authorizer = new PersonaAuthorizer(email); Authorizer = authorizer; } var facebookAccessToken = URIUtils.GetQueryParameter(uri, FacebookAuthorizer.QueryParameter); if (facebookAccessToken != null && !facebookAccessToken.IsEmpty()) { var email = URIUtils.GetQueryParameter(uri, FacebookAuthorizer.QueryParameterEmail); var authorizer = new FacebookAuthorizer(email); Uri remoteWithQueryRemoved = null; try { remoteWithQueryRemoved = new UriBuilder(remote.Scheme, remote.GetHost(), remote.Port, remote.AbsolutePath).Uri; } #if PORTABLE catch (FormatException e) #else catch (UriFormatException e) #endif { throw new ArgumentException("Invalid URI format.", "remote", e); } FacebookAuthorizer.RegisterAccessToken(facebookAccessToken, email, remoteWithQueryRemoved.ToString()); Authorizer = authorizer; } // we need to remove the query from the URL, since it will cause problems when // communicating with sync gw / couchdb try { RemoteUrl = new UriBuilder(remote.Scheme, remote.GetHost(), remote.Port, remote.AbsolutePath).Uri; } #if PORTABLE catch (FormatException e) #else catch (UriFormatException e) #endif { throw new ArgumentException("Invalid URI format.", "remote", e); } } Batcher = new Batcher<RevisionInternal>(workExecutor, InboxCapacity, ProcessorDelay, inbox => { Log.V (Database.Tag, "*** " + this + ": BEGIN processInbox (" + inbox.Count + " sequences)"); ProcessInbox (new RevisionList (inbox)); Log.V (Database.Tag, "*** " + this.ToString () + ": END processInbox (lastSequence=" + LastSequence); UpdateActive(); }, CancellationTokenSource); this.clientFactory = clientFactory ?? CouchbaseLiteHttpClientFactory.Instance; }
public void TestFacebookAuthorizer() { const string token = "pyrzqxgl"; var site = new Uri("https://example.com/database"); const string email = "*****@*****.**"; // Register and retrieve the sample token: var auth = new FacebookAuthorizer(email); auth.RemoteUrl = site; Assert.IsTrue(FacebookAuthorizer.RegisterAccessToken(token, email, site)); var gotToken = auth.GetToken(); Assert.AreEqual(token, gotToken); // Try a variant form var auth2 = new FacebookAuthorizer(email); auth2.RemoteUrl = new Uri("HttpS://example.com:443/some/other/path"); gotToken = auth2.GetToken(); Assert.AreEqual(token, gotToken); CollectionAssert.AreEqual(new ArrayList { "POST", "_facebook", new Dictionary<string, object> { ["access_token"] = token } }, auth.LoginRequest()); }