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));
        }
Beispiel #2
0
        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);
        }
Beispiel #6
0
 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());
        }