public virtual void TestParsePersonaAssertion() { try { Log.D(Database.Tag, "testParsePersonaAssertion"); string sampleAssertion = "eyJhbGciOiJSUzI1NiJ9.eyJwdWJsaWMta2V5Ijp7ImFsZ29yaXRobSI6IkRTIiwieSI6ImNhNWJiYTYzZmI4MDQ2OGE0MjFjZjgxYTIzN2VlMDcwYTJlOTM4NTY0ODhiYTYzNTM0ZTU4NzJjZjllMGUwMDk0ZWQ2NDBlOGNhYmEwMjNkYjc5ODU3YjkxMzBlZGNmZGZiNmJiNTUwMWNjNTk3MTI1Y2NiMWQ1ZWQzOTVjZTMyNThlYjEwN2FjZTM1ODRiOWIwN2I4MWU5MDQ4NzhhYzBhMjFlOWZkYmRjYzNhNzNjOTg3MDAwYjk4YWUwMmZmMDQ4ODFiZDNiOTBmNzllYzVlNDU1YzliZjM3NzFkYjEzMTcxYjNkMTA2ZjM1ZDQyZmZmZjQ2ZWZiZDcwNjgyNWQiLCJwIjoiZmY2MDA0ODNkYjZhYmZjNWI0NWVhYjc4NTk0YjM1MzNkNTUwZDlmMWJmMmE5OTJhN2E4ZGFhNmRjMzRmODA0NWFkNGU2ZTBjNDI5ZDMzNGVlZWFhZWZkN2UyM2Q0ODEwYmUwMGU0Y2MxNDkyY2JhMzI1YmE4MWZmMmQ1YTViMzA1YThkMTdlYjNiZjRhMDZhMzQ5ZDM5MmUwMGQzMjk3NDRhNTE3OTM4MDM0NGU4MmExOGM0NzkzMzQzOGY4OTFlMjJhZWVmODEyZDY5YzhmNzVlMzI2Y2I3MGVhMDAwYzNmNzc2ZGZkYmQ2MDQ2MzhjMmVmNzE3ZmMyNmQwMmUxNyIsInEiOiJlMjFlMDRmOTExZDFlZDc5OTEwMDhlY2FhYjNiZjc3NTk4NDMwOWMzIiwiZyI6ImM1MmE0YTBmZjNiN2U2MWZkZjE4NjdjZTg0MTM4MzY5YTYxNTRmNGFmYTkyOTY2ZTNjODI3ZTI1Y2ZhNmNmNTA4YjkwZTVkZTQxOWUxMzM3ZTA3YTJlOWUyYTNjZDVkZWE3MDRkMTc1ZjhlYmY2YWYzOTdkNjllMTEwYjk2YWZiMTdjN2EwMzI1OTMyOWU0ODI5YjBkMDNiYmM3ODk2YjE1YjRhZGU1M2UxMzA4NThjYzM0ZDk2MjY5YWE4OTA0MWY0MDkxMzZjNzI0MmEzODg5NWM5ZDViY2NhZDRmMzg5YWYxZDdhNGJkMTM5OGJkMDcyZGZmYTg5NjIzMzM5N2EifSwicHJpbmNpcGFsIjp7ImVtYWlsIjoiamVuc0Btb29zZXlhcmQuY29tIn0sImlhdCI6MTM1ODI5NjIzNzU3NywiZXhwIjoxMzU4MzgyNjM3NTc3LCJpc3MiOiJsb2dpbi5wZXJzb25hLm9yZyJ9.RnDK118nqL2wzpLCVRzw1MI4IThgeWpul9jPl6ypyyxRMMTurlJbjFfs-BXoPaOem878G8-4D2eGWS6wd307k7xlPysevYPogfFWxK_eDHwkTq3Ts91qEDqrdV_JtgULC8c1LvX65E0TwW_GL_TM94g3CvqoQnGVxxoaMVye4ggvR7eOZjimWMzUuu4Lo9Z-VBHBj7XM0UMBie57CpGwH4_Wkv0V_LHZRRHKdnl9ISp_aGwfBObTcHG9v0P3BW9vRrCjihIn0SqOJQ9obl52rMf84GD4Lcy9NIktzfyka70xR9Sh7ALotW7rWywsTzMTu3t8AzMz2MJgGjvQmx49QA~eyJhbGciOiJEUzEyOCJ9.eyJleHAiOjEzNTgyOTY0Mzg0OTUsImF1ZCI6Imh0dHA6Ly9sb2NhbGhvc3Q6NDk4NC8ifQ.4FV2TrUQffDya0MOxOQlzJQbDNvCPF2sfTIJN7KOLvvlSFPknuIo5g"; IDictionary<string, object> result = PersonaAuthorizer.ParseAssertion(sampleAssertion ); string email = (string)result.Get(PersonaAuthorizer.AssertionFieldEmail); string origin = (string)result.Get(PersonaAuthorizer.AssertionFieldOrigin); NUnit.Framework.Assert.AreEqual(email, "*****@*****.**"); NUnit.Framework.Assert.AreEqual(origin, "http://localhost:4984/"); NUnit.Framework.Assert.AreEqual(PersonaAuthorizer.RegisterAssertion(sampleAssertion ), email); Uri originURL = new Uri(origin); string gotAssertion = PersonaAuthorizer.AssertionForEmailAndSite(email, originURL ); NUnit.Framework.Assert.AreEqual(gotAssertion, sampleAssertion); // variant form of URL originURL = new Uri("Http://LocalHost:4984/"); gotAssertion = PersonaAuthorizer.AssertionForEmailAndSite(email, originURL); NUnit.Framework.Assert.AreEqual(sampleAssertion, gotAssertion); PersonaAuthorizer auth = new PersonaAuthorizer(email); NUnit.Framework.Assert.AreEqual(email, auth.GetEmailAddress()); NUnit.Framework.Assert.AreEqual(null, auth.AssertionForSite(originURL)); } catch (Exception e) { Sharpen.Runtime.PrintStackTrace(e); Assert.Fail(e.Message); } }
public static PersonaAuthorizer FromUri(Uri uri) { var personaAssertion = URIUtils.GetQueryParameter(uri, QueryParameter); if (personaAssertion != null && !StringEx.IsNullOrWhiteSpace(personaAssertion)) { var email = RegisterAssertion(personaAssertion); var authorizer = new PersonaAuthorizer(email); 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; }