public void TestReadPersonWithMultiplePendingModificationsActivated()
        {
            // Make a separate copy from the main tree used in other tests
            var tempTree = new FamilySearchFamilyTree(true);
            var features = new List<Feature>();

            tempTree.AuthenticateViaOAuth2Password(Resources.TestUserName, Resources.TestPassword, Resources.TestClientId);

            // Get all the features that are pending
            IRestRequest request = new RedirectableRestRequest()
                .Accept(MediaTypes.APPLICATION_JSON_TYPE)
                .Build("https://sandbox.familysearch.org/platform/pending-modifications", Method.GET);
            IRestResponse response = tempTree.Client.Handle(request);

            // Get each pending feature
            features.AddRange(response.ToIRestResponse<FamilySearchPlatform>().Data.Features);

            // Add every pending feature to the tree's current client
            tempTree.Client.AddFilter(new ExperimentsFilter(features.Select(x => x.Name).ToArray()));

            var state = tempTree.AddPerson(TestBacking.GetCreateMalePerson());
            cleanup.Add(state);

            // Ensure a response came back
            Assert.IsNotNull(state);
            var requestedFeatures = String.Join(",", state.Request.GetHeaders().Get("X-FS-Feature-Tag").Select(x => x.Value.ToString()));
            // Ensure each requested feature was found in the request headers
            Assert.IsTrue(features.TrueForAll(x => requestedFeatures.Contains(x.Name)));
        }
 public void Initialize()
 {
     tree = new FamilySearchFamilyTree(true);
     tree.AuthenticateViaOAuth2Password(Resources.TestUserName, Resources.TestPassword, Resources.TestClientId);
     Assert.DoesNotThrow(() => tree.IfSuccessful());
     Assert.IsNotNullOrEmpty(tree.CurrentAccessToken);
 }
 public void Initialize()
 {
     tree = new FamilySearchFamilyTree(true);
     tree.AuthenticateViaOAuth2Password(Resources.TestUserName, Resources.TestPassword, Resources.TestClientId);
     memories = new FamilySearchMemories(true);
     memories = (FamilySearchMemories)memories.AuthenticateWithAccessToken(tree.CurrentAccessToken).Get();
     cleanup = new List<GedcomxApplicationState>();
 }
 public void Initialize()
 {
     collection = new CollectionState(new Uri(SANDBOX_URI));
     collection.AuthenticateViaOAuth2Password(Resources.TestUserName, Resources.TestPassword, Resources.TestClientId);
     tree = new FamilySearchFamilyTree(true);
     tree.AuthenticateWithAccessToken(collection.CurrentAccessToken);
     cleanup = new List<GedcomxApplicationState>();
     Assert.DoesNotThrow(() => collection.IfSuccessful());
     Assert.IsNotNullOrEmpty(collection.CurrentAccessToken);
 }
        public void Initialize()
        {
            collection = new CollectionState(new Uri(SANDBOX_URI));
            collection.AuthenticateViaOAuth2Password("sdktester", "1234sdkpass", "WCQY-7J1Q-GKVV-7DNM-SQ5M-9Q5H-JX3H-CMJK");
            Assert.DoesNotThrow(() => collection.IfSuccessful());
            Assert.IsNotNullOrEmpty(collection.CurrentAccessToken);

            tree = new FamilySearchFamilyTree(true);
            tree.AuthenticateWithAccessToken(collection.CurrentAccessToken);
        }
 public SignInFormWizard(FamilyHistorySource fhs, FamilySearchFamilyTree ft, string username, string password,
     string developerKey)
 {
     _fhs = fhs;
     _username = username;
     _password = password;
     _developerKey = developerKey;
     _ft = ft;
     InitializeComponent();
     lblSandbox.Visible = _fhs.isSandBox;
     txtUsername.Text = _username;
     txtPassword.Text = _password;
     this.ActiveControl = txtUsername;
     txtUsername.Focus();
 }
 public void Initialize()
 {
     tree = new FamilySearchFamilyTree(true);
     tree.AuthenticateViaOAuth2Password(Resources.TestUserName, Resources.TestPassword, Resources.TestClientId);
     cleanup = new List<GedcomxApplicationState>();
 }
        private void btnSignIn_Click(object sender, EventArgs e)
        {
            String access_token = null;
            FamilySearchFamilyTree ident;


            if ((txtUsername.Text == "") || (txtPassword.Text == ""))
            {
                txtStatus.Text = "A username and password are required.";
                return;
            }

            HELPER_updateTextBox(txtStatus, "Authenticating...");

            using (new WaitCursor())
            {
                btnSignIn.Enabled = false;
                try
                {
                    #region Do it myself
                    // CRAZY LITTLE HACK - I would hope the API would do this correctly
                    // The ident.familysearch.org endpoint was not getting hit when I used the API
                    //_ft.AuthenticateViaOAuth2Password(txtUsername.Text, txtPassword.Text, _developerKey);

                    ident = new FamilySearchFamilyTree(new Uri("https://ident.familysearch.org/"));
                    //get our access token
                    IDictionary<String, String> formData = new Dictionary<String, String>();
                    formData.Add("grant_type", "password");
                    formData.Add("username", txtUsername.Text);
                    formData.Add("password", txtPassword.Text);
                    formData.Add("client_id", _developerKey);

                    IRestRequest request = new RestRequest()
                        .Accept(MediaTypes.APPLICATION_JSON_TYPE)
                        .ContentType(MediaTypes.APPLICATION_FORM_URLENCODED_TYPE)
                        .SetEntity(formData)
                        .Build("https://ident.familysearch.org/cis-web/oauth2/v3/token", Method.POST);

                    IRestResponse response = ident.Client.Handle(request);
                    var i = (int)response.StatusCode;

                    if (i >= 200 && i < 300)
                    {
                        var accessToken = JsonConvert.DeserializeObject<IDictionary<string, object>>(response.Content);
                        

                        if (accessToken.ContainsKey("access_token"))
                        {
                            access_token = accessToken["access_token"] as string;
                        }
                        if (access_token == null && accessToken.ContainsKey("token"))
                        {
                            //workaround to accommodate providers that were built on an older version of the oauth2 specification.
                            access_token = accessToken["token"] as string;
                        }

                        if (access_token == null)
                        {
                            throw new GedcomxApplicationException("Illegal access token response: no access_token provided.", response);
                        }

                    }
                    else
                    {
                        throw new GedcomxApplicationException("Unable to authenticate", response);

                    }
                    #endregion

                }
                catch (GedcomxApplicationException Ex)
                {
                    try
                    {  // if it is formatted with a Response, this will work
                        var objects = JObject.Parse(Ex.Response.Content);
                        txtStatus.Text = objects.SelectToken("error_description").Value<string>();
                    }
                    catch (Exception higherEx)
                    {   // Otherwise the above Parse will throw an exception, in this case, just read the Exception Message
                        txtStatus.Text = Ex.Message;
                    }
                    btnSignIn.Enabled = true;
                    return;
                }

                txtResults.Text = "Starting ID not verified yet.";
                txtStartingID.Focus();

                // Magic Handoff
                _ft.AuthenticateWithAccessToken(access_token);

                txtCollection.Text = _ft.Collection.Title;
                txtClient.Text = _ft.Client.BaseUrl;
                UserState userState = _ft.ReadCurrentUser();
                txtLoggedInAs.Text = userState.User.DisplayName;
                txtMyID.Text = userState.User.PersonId;

                txtStartingID.Text = _fhs.startingID;
                rbtnAncestors.Checked = _fhs.isAncestry;
                rbtnDecendants.Checked = _fhs.isDescendancy;
                rbtnBoth.Checked = _fhs.isBoth;
                numGenerations.Value = _fhs.numberOfGenerations;

                btnSignIn.Enabled = true;


                //         _memories = new FamilySearchMemories();
                //       _memories = (FamilySearchMemories)_memories.AuthenticateWithAccessToken(access_token).Get();
                //     var state = _memories.ReadResourcesOfCurrentUser();



                HELPER_updateTextBox(txtStatus, "Collecting direct ancestors...");


                fillAncestorTreePicker(_ft, treAncestorPicker.Nodes);


                tabWizard.SelectedIndex = (tabWizard.SelectedIndex + 1 < tabWizard.TabCount)
                    ? tabWizard.SelectedIndex + 1
                    : tabWizard.SelectedIndex;
            }
        }
        private void fillAncestorTreePicker(FamilySearchFamilyTree myFT, TreeNodeCollection myTreeNodeCollection)
        {
            PersonParentsState parentsState;
            List<TreeNode> myParentsTreeNodes;
            TreeNode node;

            UserState userState = myFT.ReadCurrentUser();
            var startingID = userState.User.PersonId;
            var personState = (PersonState)myFT.ReadPersonById(startingID);

            HELPER_updateTextBox(txtStatus, "Collecting direct ancestors... " + personState.Person.DisplayExtension.Name);

            parentsState = personState.ReadParents();
            myParentsTreeNodes = new List<TreeNode>();
            foreach (var parentPerson in parentsState.Persons)
            {
                HELPER_updateTextBox(txtStatus, "Collecting direct ancestors... " + parentPerson.DisplayExtension.Name);
                TreeNode aNode = ancestryToTreeNode((PersonState)myFT.ReadPersonById(parentPerson.Id));
                myParentsTreeNodes.Add(aNode);
            }
            
            node = new TreeNode(personState.Person.DisplayExtension.Name + ": " + startingID, myParentsTreeNodes.ToArray());

            myTreeNodeCollection.Add(node);

            // Repeat for my Spouce(s)

            PersonSpousesState spousesState = personState.ReadSpouses();

            foreach (var spousePerson in spousesState.Persons)
            {
                var spouseId = spousePerson.Id;
                var spouseState = (PersonState)myFT.ReadPersonById(spouseId);

                HELPER_updateTextBox(txtStatus, "Collecting direct ancestors... " + spouseState.Person.DisplayExtension.Name);

                parentsState = spouseState.ReadParents();
                myParentsTreeNodes = new List<TreeNode>();
                foreach (var parentPerson in parentsState.Persons)
                {
                    HELPER_updateTextBox(txtStatus, "Collecting direct ancestors... " + parentPerson.DisplayExtension.Name);
                    TreeNode aNode = ancestryToTreeNode((PersonState)myFT.ReadPersonById(parentPerson.Id));
                    myParentsTreeNodes.Add(aNode);
                }

                node = new TreeNode(spousePerson.DisplayExtension.Name + ": " + spouseId, myParentsTreeNodes.ToArray());

                myTreeNodeCollection.Add(node);
            }

        }
        public bool initializeConnection()
        {
            if (isFamilySearch)
            {
                #region Comments galore regarding the GEDCOMX and FamilySearch API
                /* * * * * * * *
                FamilySearch C# SDK info:
                https://familysearch.org/developers/libraries/csharp
                https://www.nuget.org/packages/FamilySearch.API.SDK/
                https://github.com/FamilySearch/gedcomx-csharp
                https://github.com/FamilySearch/gedcomx/tree/master/specifications

                //Documentation
                //https://github.com/FamilySearch/gedcomx/blob/master/specifications/conceptual-model-specification.md

                URL: https://sandbox.familysearch.org 

                Usefull online utility to copy a tree from production to the sandbox
                http://familysearch.github.io/sandbox-data-copy/

                * * * * * * */
                #endregion

                if (ft == null)
                    ft = new FamilySearchFamilyTree(isSandBox); // true means sandbox reference. 
          
                Form signInForm = new SignInFormWizard(this, ft, username, password, appKey);
           
                var dialogRet = signInForm.ShowDialog();

                if (dialogRet == DialogResult.Cancel)
                {
                    return false;
                }

                if (!ft.IsAuthenticated)
                    throw new Exception("Authentication to FamilySearch Failed");

                return true;
            }

            throw new NotImplementedException("This connection type NOT IMPLEMENTED YET");
        }