Beispiel #1
0
        public static bool Export(string connectionString, string filename, string username)
        {
            var context = new UserStorageContext(connectionString);
            var user    = context.Users.FirstOrDefault(u => u.Name == username);

            if (user == null)
            {
                Console.WriteLine(String.Format("Export: user {0} not found", username));
                return(false);
            }

            var userDataModel = new UserDataModel(context, user);

            try
            {
                filename = filename ?? @"userdata.json";
                using (var stream = File.Create(filename))
                    using (var writer = new StreamWriter(stream))
                    {
                        writer.WriteLine(userDataModel.JsonUserData);
                        writer.Flush();
                    }
            }
            catch (Exception ex)
            {
                Console.WriteLine("Export: write failed; ex: ", ex.Message);
                return(false);
            }
            return(true);
        }
Beispiel #2
0
        /// <summary>
        /// Event handler for the  access token received event. This method should save the tokens so that
        /// they can be used by the application in its requests.
        /// </summary>
        /// <param name="sender">Sender of the event.</param>
        /// <param name="tokenReceivedEventArgs">Event arguments.</param>
        void OAuthClientSettings_AccessTokenReceived(object sender, AccessTokenReceivedEventArgs tokenReceivedEventArgs)
        {
            string accessToken  = tokenReceivedEventArgs.AuthorizationResponse.Parameters[OAuthConstants.AccessToken];
            Uri    tokenUri     = tokenReceivedEventArgs.TokenUri;
            string refreshToken = tokenReceivedEventArgs.AuthorizationResponse.Parameters[OAuthConstants.RefreshToken];

            if (tokenReceivedEventArgs.Resource.StartsWith(AzureOAuthConfiguration.ProtectedResourceUrl))
            {
                User user = null;
                UserStorageContext userStorage = Storage.NewUserContext;
                try
                {   // store token
                    var userid = new Guid(tokenReceivedEventArgs.State);
                    user = userStorage.GetUser(userid, true);
                    user.AddCredential(UserCredential.CloudADConsent, accessToken, null, refreshToken);
                    userStorage.SaveChanges();
                }
                catch (Exception ex)
                {
                    TraceLog.TraceException("Failed to store CloudAD consent token for User", ex);
                    tokenReceivedEventArgs.HttpContext.Response.Redirect("dashboard/home?consentStatus=" + UserDataModel.CloudADConsentFail, true);
                }

                // redirect back to the dashboard
                tokenReceivedEventArgs.HttpContext.Response.Redirect("dashboard/home?consentStatus=" + UserDataModel.CloudADConsentSuccess, true);
            }
        }
Beispiel #3
0
        /// <summary>
        /// Restart the workflows associated with an entity
        /// </summary>
        /// <param name="userContext"></param>
        /// <param name="suggestionsContext"></param>
        /// <param name="entity"></param>
        /// <param name="workflowType"></param>
        public static void RestartWorkflow(UserStorageContext userContext, SuggestionsStorageContext suggestionsContext, ServerEntity entity, string workflowType)
        {
            if (entity == null || workflowType == null)
            {
                return;
            }

            try
            {
                // kill all existing workflows associated with this Item
                // TODO: also need to mark the suggestions associated with this workflow as stale so that they don't
                // show up for the item again.
                var runningWFs = suggestionsContext.WorkflowInstances.Where(wi => wi.EntityID == entity.ID).ToList();
                if (runningWFs.Count > 0)
                {
                    foreach (var wf in runningWFs)
                    {
                        suggestionsContext.WorkflowInstances.Remove(wf);
                    }
                    suggestionsContext.SaveChanges();
                }
                StartWorkflow(userContext, suggestionsContext, workflowType, entity, null);
            }
            catch (Exception)
            {
                StartWorkflow(userContext, suggestionsContext, workflowType, entity, null);
            }
        }
Beispiel #4
0
        public override void UpdateUser(MembershipUser mu)
        {   // TODO: allow update of more than just email?
            UserStorageContext storage = Storage.NewUserContext;
            User user = storage.Users.Single <User>(u => u.Name == mu.UserName);

            user.Email = mu.Email;
            storage.SaveChanges();
        }
Beispiel #5
0
        public static bool GetUserInfo(User user, UserStorageContext storage)
        {
            // set up the FB API context
            FBGraphAPI fbApi = new FBGraphAPI();
            UserCredential cred = user.GetCredential(UserCredential.FacebookConsent);
            if (cred != null && cred.AccessToken != null)
            {
                fbApi.AccessToken = cred.AccessToken;
            }
            else
            {
                TraceLog.TraceError(TRACE_NO_FB_TOKEN);
                return false;
            }

            // store user information from Facebook in UserProfile
            UserProfile userProfile = storage.ClientFolder.GetUserProfile(user);
            if (userProfile == null)
            {
                TraceLog.TraceError("Could not access UserProfile to import Facebook information into.");
                return false;
            }

            try
            {   // import information about the current user
                // using foreach because the Query API returns an IEnumerable, but there is only one result
                foreach (var userInfo in fbApi.Query("me", FBQueries.BasicInformation))
                {
                    // import FacebookID
                    userProfile.FacebookID = (string)userInfo[FBQueryResult.ID];
                    // import name if not already set
                    if (userProfile.FirstName == null)
                        userProfile.FirstName = (string)userInfo["first_name"];
                    if (userProfile.LastName == null)
                        userProfile.LastName = (string)userInfo["last_name"];
                    // import picture if not already set
                    if (userProfile.Picture == null)
                        userProfile.Picture = String.Format("https://graph.facebook.com/{0}/picture", userProfile.FacebookID);
                    // import birthday if not already set
                    if (userProfile.Birthday == null)
                        userProfile.Birthday = (string)userInfo[FBQueryResult.Birthday];
                    // import gender if not already set
                    if (userProfile.Gender == null)
                        userProfile.Gender = (string)userInfo[FBQueryResult.Gender];
                    // import geolocation if not already set
                    if (userProfile.GeoLocation == null)
                        userProfile.GeoLocation = (string)((FBQueryResult)userInfo[FBQueryResult.Location])[FBQueryResult.Name];
                    TraceLog.TraceInfo("Imported Facebook information into UserProfile");
                }
            }
            catch (Exception ex)
            {
                TraceLog.TraceException("Facebook query for basic User information failed", ex);
                return false;
            }
            return true;
        }
Beispiel #6
0
        public static bool SaveCredential(string username, string credentialType, string accessToken, DateTime?expires, string renewalToken = null)
        {
            UserStorageContext storage = Storage.NewUserContext;
            User user   = storage.Users.Include("UserCredentials").Single <User>(u => u.Name == username);
            bool exists = user.AddCredential(credentialType, accessToken, expires, renewalToken);

            storage.SaveChanges();
            return(exists);
        }
        /// <summary>
        /// Add a Contact to the possible contacts list
        /// </summary>
        /// <param name="userContext"></param>
        /// <param name="item"></param>
        /// <returns>false if errors were encountered, otherwise true</returns>
        public static bool AddContact(UserStorageContext userContext, Item item)
        {
            User user = userContext.GetUser(item.UserID);
            Item possibleContactsList = userContext.UserFolder.GetListForItemType(user, SystemItemTypes.Contact);
            if (possibleContactsList == null)
            {
                TraceLog.TraceError("Could not retrieve or create the possible contacts list");
                return false;
            }

            try
            {
                // determine if a possible contact by this name already exists, and if so, skip adding it
                var nameValItem = userContext.Items.Include("FieldValues").FirstOrDefault(
                    ps => ps.UserID == user.ID && ps.FolderID == possibleContactsList.FolderID &&
                    ps.Name == item.Name && ps.ParentID == possibleContactsList.ID && ps.ItemTypeID == SystemItemTypes.NameValue);

                if (nameValItem == null)
                {
                    // store the serialized contact in the value of a new NameValue item on the PossibleContacts list
                    string jsonContact = JsonSerializer.Serialize(item);

                    Guid id = Guid.NewGuid();
                    DateTime now = DateTime.UtcNow;
                    nameValItem = new Item()
                    {
                        ID = id,
                        Name = item.Name,
                        FolderID = possibleContactsList.FolderID,
                        ParentID = possibleContactsList.ID,
                        UserID = user.ID,
                        ItemTypeID = SystemItemTypes.NameValue,
                        Created = now,
                        LastModified = now,
                        FieldValues = new List<FieldValue>() { new FieldValue() { FieldName = FieldNames.Value, ItemID = id, Value = jsonContact } }
                    };

                    // add the new possible contact to the DB
                    userContext.Items.Add(nameValItem);
                }

                // store a reference fieldvalue on the namevalue item to designate that this possible contact relates to an existing Contact
                nameValItem.GetFieldValue(FieldNames.EntityRef, true).Value = item.ID.ToString();
                nameValItem.GetFieldValue(FieldNames.EntityType, true).Value = EntityTypes.Item;

                // store the updated possible contact in the DB
                userContext.SaveChanges();
            }
            catch (Exception ex)
            {
                TraceLog.TraceException("Could not create a new PossibleContact", ex);
                return false;
            }

            return true;
        }
Beispiel #8
0
        public static bool AddContactInfo(UserStorageContext userContext, Item item)
        {
            FieldValue fbfv = item.GetFieldValue(FieldNames.FacebookID);
            if (fbfv == null)
                return true;

            User user = userContext.GetUser(item.UserID, true);
            if (user == null)
                return false;

            // set up the FB API context
            FBGraphAPI fbApi = new FBGraphAPI();
            UserCredential cred = user.GetCredential(UserCredential.FacebookConsent);
            if (cred != null && cred.AccessToken != null)
            {
                fbApi.AccessToken = cred.AccessToken;
            }
            else
            {
                TraceLog.TraceError(TRACE_NO_FB_TOKEN);
                return false;
            }

            // get or create an EntityRef in the UserFolder EntityRefs list
            var entityRefItem = userContext.UserFolder.GetEntityRef(user, item);
            if (entityRefItem == null)
            {
                TraceLog.TraceError(TRACE_NO_CONTACT_ENTITYREF);
                return false;
            }

            try
            {   // get the Contact information from Facebook
                // using foreach because the Query API returns an IEnumerable, but there is only one result
                foreach (var contact in fbApi.Query(fbfv.Value, FBQueries.BasicInformation))
                {
                    item.GetFieldValue(FieldNames.Picture, true).Value = String.Format("https://graph.facebook.com/{0}/picture", fbfv.Value);
                    var birthday = (string)contact[FBQueryResult.Birthday];
                    if (birthday != null)
                        item.GetFieldValue(FieldNames.Birthday, true).Value = birthday;
                    var gender = (string)contact[FBQueryResult.Gender];
                    if (gender != null)
                        entityRefItem.GetFieldValue(FieldNames.Gender, true).Value = gender;
                }
                userContext.SaveChanges();
            }
            catch (Exception ex)
            {
                TraceLog.TraceException(TRACE_NO_SAVE_FBCONTACTINFO, ex);
                return false;
            }

            return true;
        }
Beispiel #9
0
 /// <summary>
 /// Invoke the workflows for an operation depending on the environment.
 /// If in Azure, enqueue a message; otherwise, invoke the workflow host directly.
 /// </summary>
 /// <param name="userContext"></param>
 /// <param name="suggestionsContext"></param>
 /// <param name="operation"></param>
 public static void InvokeWorkflowForOperation(UserStorageContext userContext, SuggestionsStorageContext suggestionsContext, Operation operation)
 {
     if (HostEnvironment.IsAzure)
     {
         MessageQueue.EnqueueMessage(operation.ID);
     }
     else
     {
         ProcessOperation(userContext, suggestionsContext, operation);
     }
 }
        /// <summary>
        /// Remove a Contact from the possible contacts list
        /// </summary>
        /// <param name="userContext"></param>
        /// <param name="item"></param>
        /// <returns></returns>
        public static bool RemoveContact(UserStorageContext userContext, Item item)
        {
            // clean up any possible contacts that have this ID
            User user = userContext.GetUser(item.UserID);
            Item possibleContactsList = userContext.UserFolder.GetListForItemType(user, SystemItemTypes.Contact);

            if (possibleContactsList == null)
            {
                return(false);
            }

            try
            {
                // find the item in the possible contacts list that corresponds to this contact
                var idstring        = item.ID.ToString();
                var possibleContact = userContext.Items.Include("FieldValues").FirstOrDefault(ps => ps.UserID == user.ID && ps.FolderID == possibleContactsList.FolderID &&
                                                                                              ps.ParentID == possibleContactsList.ID && ps.FieldValues.Any(fv => fv.FieldName == FieldNames.EntityRef && fv.Value == idstring));
                if (possibleContact == null)
                {
                    return(true);
                }

                // if this possible contact didn't come from facebook, remove it
                if (possibleContact.GetFieldValue(FieldNames.FacebookID) == null)
                {
                    userContext.Items.Remove(possibleContact);
                    return(true);
                }

                // leave the possible contact, but remove the fieldvalues on this possible contact that relate it to the deleted contact
                var fieldVal = possibleContact.GetFieldValue(FieldNames.EntityRef);
                if (fieldVal != null)
                {
                    userContext.FieldValues.Remove(fieldVal);
                }
                fieldVal = possibleContact.GetFieldValue(FieldNames.EntityType);
                if (fieldVal != null)
                {
                    userContext.FieldValues.Remove(fieldVal);
                }
                userContext.SaveChanges();

                return(true);
            }
            catch (Exception ex)
            {
                TraceLog.TraceException("Could not delete the PossibleContact " + item.Name, ex);
                return(false);
            }
        }
Beispiel #11
0
        public override bool DeleteUser(string username, bool deleteAllRelatedData)
        {   // always delete all related data
            UserStorageContext storage = Storage.NewUserContext;
            User dbUser = storage.Users.
                          Include("ItemTypes.Fields").
                          Include("Tags").
                          Include("Items.ItemTags").
                          Include("Folders.FolderUsers").
                          Single <User>(u => u.Name == username.ToLower());

            storage.Users.Remove(dbUser);
            int rows = storage.SaveChanges();

            return(rows > 0);
        }
Beispiel #12
0
        public override bool ValidateUser(string username, string password)
        {
            UserStorageContext storage = Storage.NewUserContext;
            User user = LookupUserByName(username, true, storage);

            if (user != null)
            {
                UserCredential cred = user.UserCredentials.Single <UserCredential>(uc => uc.CredentialType == UserCredential.Password);
                if (IsValidPassword(cred, password))
                {   // timestamp LastAccessed
                    cred.LastAccessed = DateTime.UtcNow;
                    storage.SaveChanges();
                    return(true);
                }
            }
            return(false);
        }
Beispiel #13
0
        static User LookupUserByEmail(string email, bool includeCredentials = false)
        {
            email = email.ToLower();
            UserStorageContext storage = Storage.NewUserContext;

            if (storage.Users.Any <User>(u => u.Email == email))
            {
                if (includeCredentials)
                {
                    return(storage.Users.Include("UserCredentials").Single <User>(u => u.Email == email));
                }
                else
                {
                    return(storage.Users.Single <User>(u => u.Email == email));
                }
            }
            return(null);
        }
Beispiel #14
0
        public static bool DeleteItemChildrenRecursively(UserStorageContext storageContext, Item item)
        {
            var  children = storageContext.Items.Where(i => i.ParentID == item.ID).ToList();
            bool commit   = false;

            foreach (var c in children)
            {
                DeleteItemChildrenRecursively(storageContext, c);
                storageContext.Items.Remove(c);
                commit = true;
            }

            // commit deletion of all children at the same layer together
            if (commit)
            {
                storageContext.SaveChanges();
            }
            return(commit);
        }
Beispiel #15
0
        /// <summary>
        /// Start NewUser/NewFolder/NewItem workflows based on the entity type
        /// </summary>
        /// <param name="userContext"></param>
        /// <param name="suggestionsContext"></param>
        /// <param name="entity"></param>
        public static void StartNewWorkflows(UserStorageContext userContext, SuggestionsStorageContext suggestionsContext, ServerEntity entity)
        {
            if (entity == null)
            {
                return;
            }

            // figure out what kind of entity this is
            Item   item   = entity as Item;
            Folder folder = entity as Folder;
            User   user   = entity as User;

            // verify there are no workflow instances associated with this item yet
            var wis = suggestionsContext.WorkflowInstances.Where(wi => wi.EntityID == entity.ID).ToList();

            if (wis.Count > 0)
            {
                return;
            }

            if (item != null && item.IsList == false)
            {
                if (item.ItemTypeID == SystemItemTypes.Task)
                {
                    StartWorkflow(userContext, suggestionsContext, WorkflowNames.NewTask, item, null);
                }
                // the Contact and Grocery new item processing happens in ItemProcessor now
                //if (item.ItemTypeID == SystemItemTypes.Contact)
                //    StartWorkflow(userContext, suggestionsContext, WorkflowNames.NewContact, item, null);
                //if (item.ItemTypeID == SystemItemTypes.Grocery)
                //    Workflow.StartWorkflow(userContext, suggestionsContext, WorkflowNames.NewGrocery, item, null);
            }

            if (folder != null)
            {
            }

            if (user != null)
            {
                StartWorkflow(userContext, suggestionsContext, WorkflowNames.NewUser, user, null);
            }
        }
        /// <summary>
        /// Remove a Contact from the possible contacts list
        /// </summary>
        /// <param name="userContext"></param>
        /// <param name="item"></param>
        /// <returns></returns>
        public static bool RemoveContact(UserStorageContext userContext, Item item)
        {
            // clean up any possible contacts that have this ID
            User user = userContext.GetUser(item.UserID);
            Item possibleContactsList = userContext.UserFolder.GetListForItemType(user, SystemItemTypes.Contact);
            if (possibleContactsList == null)
                return false;

            try
            {
                // find the item in the possible contacts list that corresponds to this contact
                var idstring = item.ID.ToString();
                var possibleContact = userContext.Items.Include("FieldValues").FirstOrDefault(ps => ps.UserID == user.ID && ps.FolderID == possibleContactsList.FolderID &&
                    ps.ParentID == possibleContactsList.ID && ps.FieldValues.Any(fv => fv.FieldName == FieldNames.EntityRef && fv.Value == idstring));
                if (possibleContact == null)
                    return true;

                // if this possible contact didn't come from facebook, remove it
                if (possibleContact.GetFieldValue(FieldNames.FacebookID) == null)
                {
                    userContext.Items.Remove(possibleContact);
                    return true;
                }

                // leave the possible contact, but remove the fieldvalues on this possible contact that relate it to the deleted contact
                var fieldVal = possibleContact.GetFieldValue(FieldNames.EntityRef);
                if (fieldVal != null)
                    userContext.FieldValues.Remove(fieldVal);
                fieldVal = possibleContact.GetFieldValue(FieldNames.EntityType);
                if (fieldVal != null)
                    userContext.FieldValues.Remove(fieldVal);
                userContext.SaveChanges();

                return true;
            }
            catch (Exception ex)
            {
                TraceLog.TraceException("Could not delete the PossibleContact " + item.Name, ex);
                return false;
            }
        }
Beispiel #17
0
 /// <summary>
 /// Delete all workflow instances associated with this entity ID (the entity is already deleted)
 /// </summary>
 /// <param name="userContext"></param>
 /// <param name="suggestionsContext"></param>
 /// <param name="entity"></param>
 public static void DeleteWorkflows(UserStorageContext userContext, SuggestionsStorageContext suggestionsContext, Guid entityID)
 {
     try
     {
         // get all the workflow instances for this Item
         var wis = suggestionsContext.WorkflowInstances.Where(w => w.EntityID == entityID).ToList();
         if (wis.Count > 0)
         {
             // loop over the workflow instances and dispatch the new message
             foreach (var instance in wis)
             {
                 suggestionsContext.WorkflowInstances.Remove(instance);
             }
             suggestionsContext.SaveChanges();
         }
     }
     catch (Exception ex)
     {
         TraceLog.TraceException("DeleteWorkflows failed", ex);
     }
 }
Beispiel #18
0
 public override bool ChangePassword(string username, string oldPassword, string newPassword)
 {
     try
     {
         UserStorageContext storage = Storage.NewUserContext;
         User           user        = storage.Users.Include("UserCredentials").Single <User>(u => u.Name == username.ToLower());
         UserCredential cred        = user.UserCredentials.Single <UserCredential>(uc => uc.CredentialType == UserCredential.Password);
         // verify old password
         if (IsValidPassword(cred, oldPassword))
         {   // TODO: verify new password meets requirements
             cred.AccessToken  = HashPassword(newPassword, cred.RenewalToken);
             cred.LastModified = DateTime.UtcNow;
             return(storage.SaveChanges() > 0);
         }
     }
     catch (Exception ex)
     {
         TraceLog.TraceException("ChangePassword", ex);
     }
     return(false);
 }
Beispiel #19
0
        public static bool DeleteItemReferences(User currentUser, UserStorageContext storageContext, Item item)
        {
            string itemID   = item.ID.ToString();
            var    itemRefs = storageContext.Items.Include("FieldValues").
                              Where(i => i.UserID == currentUser.ID && i.ItemTypeID == SystemItemTypes.Reference &&
                                    i.FieldValues.Any(fv => fv.FieldName == FieldNames.EntityRef && fv.Value == itemID)).ToList();
            bool commit = false;

            foreach (var itemRef in itemRefs)
            {
                storageContext.Items.Remove(itemRef);
                commit = true;
            }

            // commit deletion of References
            if (commit)
            {
                storageContext.SaveChanges();
            }
            return(commit);
        }
Beispiel #20
0
        /// <summary>
        /// Start workflows associated with a change in one or more of the entity's fields
        /// </summary>
        /// <param name="userContext"></param>
        /// <param name="suggestionsContext"></param>
        /// <param name="entity"></param>
        /// <param name="oldEntity"></param>
        public static void StartTriggerWorkflows(UserStorageContext userContext, SuggestionsStorageContext suggestionsContext, ServerEntity entity, ServerEntity oldEntity)
        {
            if (entity == null || oldEntity == null)
            {
                return;
            }

            // only Item property triggers are supported at this time
            Item item    = entity as Item;
            Item oldItem = oldEntity as Item;

            if (item != null)
            {
                // go through field by field, and if a field has changed, trigger the appropriate workflow
                ItemType itemType = userContext.ItemTypes.Include("Fields").Single(it => it.ID == item.ItemTypeID);

                foreach (var field in itemType.Fields)
                {
                    object newValue = item.GetFieldValue(field);
                    object oldValue = item.GetFieldValue(field);

                    // skip fields that haven't changed
                    if (newValue == null || newValue.Equals(oldValue))
                    {
                        continue;
                    }

                    // do field-specific processing for select fields
                    switch (field.Name)
                    {
                    case FieldNames.Name:
                        //disable for now
                        //RestartWorkflow(userContext, suggestionsContext, item, WorkflowNames.NewTask);
                        break;
                    }
                }
            }
        }
Beispiel #21
0
 public UserDataModel(BaseController controller)
 {
     this.storageContext = controller.StorageContext;
     this.currentUser    = controller.CurrentUser;
 }
Beispiel #22
0
 static User LookupUserByName(string username, bool includeCredentials = false, UserStorageContext storage = null)
 {
     username = username.ToLower();
     if (storage == null)
     {
         storage = Storage.NewUserContext;
     }
     if (storage.Users.Any <User>(u => u.Name == username))
     {
         if (includeCredentials)
         {
             return(storage.Users.Include("UserCredentials").Single <User>(u => u.Name == username));
         }
         else
         {
             return(storage.Users.Single <User>(u => u.Name == username));
         }
     }
     return(null);
 }
Beispiel #23
0
        public static bool PostQuestion(User user, UserStorageContext storage, string question)
        {
            // set up the FB API context
            FBGraphAPI fbApi = new FBGraphAPI();
            UserCredential cred = user.GetCredential(UserCredential.FacebookConsent);
            if (cred != null && cred.AccessToken != null)
            {
                fbApi.AccessToken = cred.AccessToken;
            }
            else
            {
                TraceLog.TraceError(TRACE_NO_FB_TOKEN);
                return false;
            }

            try
            {
                // using foreach because the Post API returns an IEnumerable, but there is only one result
                foreach (var result in fbApi.Post("me", FBQueries.Questions, "question=" + question))
                {
                    var id = result[FBQueryResult.ID];
                    if (id != null)
                        TraceLog.TraceInfo(String.Format("Posted question {0} to Facebook", id));
                    else
                        TraceLog.TraceInfo("Unknown response received for posting question to Facebook");
                    break;
                }
            }
            catch (Exception ex)
            {
                TraceLog.TraceException("Posting to Facebook failed", ex);
                return false;
            }
            return true;
        }
 public PasswordValidator(UserStorageContext userContext)
 {
     _userContext = userContext;
 }
Beispiel #25
0
        /// <summary>
        /// Execute the workflow instances associated with this entity
        /// </summary>
        /// <param name="entity"></param>
        /// <param name="userContext"></param>
        /// <param name="suggestionsContext"></param>
        /// <returns>true if processing happened (and the operation doesn't need to be processed again),
        /// false if one the workflow instances was locked (causes the message to be reprocessed)</returns>
        public static bool ExecuteWorkflows(UserStorageContext userContext, SuggestionsStorageContext suggestionsContext, ServerEntity entity)
        {
            if (entity == null)
            {
                return(true);
            }

            List <WorkflowInstance> wis = null;

            try
            {
                // get all the workflow instances for this Item
                wis = suggestionsContext.WorkflowInstances.Where(w => w.EntityID == entity.ID).ToList();
                if (wis.Count > 0)
                {
                    // if the instance is locked by someone else, stop processing
                    // otherwise lock each of the workflow instances
                    foreach (var instance in wis)
                    {
                        if (instance.LockedBy != null && instance.LockedBy != Me)
                        {
                            return(false);
                        }
                        instance.LockedBy = Me;
                    }
                    suggestionsContext.SaveChanges();

                    // reacquire the lock list and verify they were all locked by Me (if not, stop processing)
                    // projecting locks and not workflow instances to ensure that the database's lock values are returned (not from EF's cache)
                    var locks = suggestionsContext.WorkflowInstances.Where(w => w.EntityID == entity.ID).Select(w => w.LockedBy).ToList();
                    foreach (var lockedby in locks)
                    {
                        if (lockedby != Me)
                        {
                            return(false);
                        }
                    }

                    // loop over the workflow instances and dispatch the new message
                    foreach (var instance in wis)
                    {
                        Workflow workflow = null;
                        try
                        {
                            var wt = suggestionsContext.WorkflowTypes.Single(t => t.Type == instance.WorkflowType);
                            workflow = JsonSerializer.Deserialize <Workflow>(wt.Definition);
                        }
                        catch (Exception ex)
                        {
                            TraceLog.TraceException("Could not find or deserialize workflow definition", ex);
                            continue;
                        }

                        // set the database contexts
                        workflow.UserContext        = userContext;
                        workflow.SuggestionsContext = suggestionsContext;

                        // invoke the workflow and process steps until workflow is blocked for user input or is done
                        workflow.Run(instance, entity);
                    }
                }
                return(true);
            }
            catch (Exception ex)
            {
                TraceLog.TraceException("ExecuteWorkflows failed", ex);
                return(true);
            }
            finally
            {
                // find and unlock all remaining workflow instances that relate to this entity
                // note that a new context is used for this - to avoid caching problems where the current thread
                // believes it is the owner but the database says otherwise.
                var context = Storage.NewSuggestionsContext;
                wis = context.WorkflowInstances.Where(w => w.EntityID == entity.ID).ToList();
                if (wis.Count > 0)
                {
                    // unlock each of the workflow instances
                    foreach (var instance in wis)
                    {
                        if (instance.LockedBy == Me)
                        {
                            instance.LockedBy = null;
                        }
                    }
                    context.SaveChanges();
                }
            }
        }
Beispiel #26
0
        public static bool GetUserInfo(User user, UserStorageContext storage)
        {
            // set up the FB API context
            FBGraphAPI     fbApi = new FBGraphAPI();
            UserCredential cred  = user.GetCredential(UserCredential.FacebookConsent);

            if (cred != null && cred.AccessToken != null)
            {
                fbApi.AccessToken = cred.AccessToken;
            }
            else
            {
                TraceLog.TraceError(TRACE_NO_FB_TOKEN);
                return(false);
            }

            // store user information from Facebook in UserProfile
            UserProfile userProfile = storage.ClientFolder.GetUserProfile(user);

            if (userProfile == null)
            {
                TraceLog.TraceError("Could not access UserProfile to import Facebook information into.");
                return(false);
            }

            try
            {   // import information about the current user
                // using foreach because the Query API returns an IEnumerable, but there is only one result
                foreach (var userInfo in fbApi.Query("me", FBQueries.BasicInformation))
                {
                    // import FacebookID
                    userProfile.FacebookID = (string)userInfo[FBQueryResult.ID];
                    // import name if not already set
                    if (userProfile.FirstName == null)
                    {
                        userProfile.FirstName = (string)userInfo["first_name"];
                    }
                    if (userProfile.LastName == null)
                    {
                        userProfile.LastName = (string)userInfo["last_name"];
                    }
                    // import picture if not already set
                    if (userProfile.Picture == null)
                    {
                        userProfile.Picture = String.Format("https://graph.facebook.com/{0}/picture", userProfile.FacebookID);
                    }
                    // import birthday if not already set
                    if (userProfile.Birthday == null)
                    {
                        userProfile.Birthday = (string)userInfo[FBQueryResult.Birthday];
                    }
                    // import gender if not already set
                    if (userProfile.Gender == null)
                    {
                        userProfile.Gender = (string)userInfo[FBQueryResult.Gender];
                    }
                    // import geolocation if not already set
                    if (userProfile.GeoLocation == null)
                    {
                        userProfile.GeoLocation = (string)((FBQueryResult)userInfo[FBQueryResult.Location])[FBQueryResult.Name];
                    }
                    TraceLog.TraceInfo("Imported Facebook information into UserProfile");
                }
            }
            catch (Exception ex)
            {
                TraceLog.TraceException("Facebook query for basic User information failed", ex);
                return(false);
            }
            return(true);
        }
Beispiel #27
0
        public static bool ImportFriendsAsPossibleContacts(User user, UserStorageContext userContext)
        {
            // set up the FB API context
            FBGraphAPI     fbApi = new FBGraphAPI();
            UserCredential cred  = user.GetCredential(UserCredential.FacebookConsent);

            if (cred != null && cred.AccessToken != null)
            {
                fbApi.AccessToken = cred.AccessToken;
            }
            else
            {
                TraceLog.TraceError(TRACE_NO_FB_TOKEN);
                return(false);
            }

            // get or create the list for Contact item types in the UserFolder
            Item possibleContactsList = userContext.UserFolder.GetListForItemType(user, SystemItemTypes.Contact);

            if (possibleContactsList == null)
            {
                TraceLog.TraceError("Could not retrieve or create the possible contacts list");
                return(false);
            }

            // get the current list of all possible contacts for this user
            var currentPossibleContacts = userContext.Items.Include("FieldValues").Where(ps => ps.UserID == user.ID && ps.FolderID == possibleContactsList.FolderID &&
                                                                                         ps.ParentID == possibleContactsList.ID && ps.ItemTypeID == SystemItemTypes.NameValue &&
                                                                                         ps.FieldValues.Any(fv => fv.FieldName == FieldNames.FacebookID)).ToList();

            // get the current list of all Items that are Contacts for this user
            var currentContacts = userContext.Items.Include("FieldValues").
                                  Where(c => c.UserID == user.ID && c.ItemTypeID == SystemItemTypes.Contact).ToList();

            // get all the user's friends and add them as serialized contacts to the possible contacts list
            DateTime now = DateTime.UtcNow;

            try
            {
                var results = fbApi.Query("me", FBQueries.Friends).ToList();
                TraceLog.TraceInfo(String.Format("Found {0} Facebook friends", results.Count));
                foreach (var friend in results)
                {
                    // check if a possible contact by this name and with this FBID already exists - and if so, skip it
                    if (currentPossibleContacts.Any(
                            ps => ps.Name == (string)friend[FBQueryResult.Name] &&
                            ps.FieldValues.Any(fv => fv.FieldName == FieldNames.FacebookID && fv.Value == (string)friend[FBQueryResult.ID])))
                    {
                        continue;
                    }

                    bool process = true;

                    // check if a contact by this name already exists
                    var existingContacts = currentContacts.Where(c => c.Name == (string)friend[FBQueryResult.Name]).ToList();
                    foreach (var existingContact in existingContacts)
                    {
                        var fbFV = existingContact.GetFieldValue(FieldNames.FacebookID, true);
                        if (fbFV.Value == null)
                        {
                            // contact with this name exists but no FacebookID, assume same and set the FacebookID
                            fbFV.Value = (string)friend[FBQueryResult.ID];
                            var sourcesFV = existingContact.GetFieldValue(FieldNames.Sources, true);
                            sourcesFV.Value = string.IsNullOrEmpty(sourcesFV.Value) ? Sources.Facebook : string.Concat(sourcesFV.Value, ",", Sources.Facebook);
                            process         = false;
                            break;
                        }
                        if (fbFV.Value == (string)friend[FBQueryResult.ID])
                        {   // FacebookIDs are same, definitely a duplicate, do not add
                            process = false;
                            break;
                        }
                        // contact with same name was found but had a different FacebookID, add as a new contact
                    }

                    // add contact if not a duplicate
                    if (process)
                    {
                        var contact = new Item()
                        {
                            ID          = Guid.NewGuid(),
                            Name        = (string)friend[FBQueryResult.Name],
                            UserID      = user.ID,
                            ItemTypeID  = SystemItemTypes.Contact,
                            FieldValues = new List <FieldValue>(),
                        };
                        contact.FieldValues.Add(new FieldValue()
                        {
                            ItemID = contact.ID, FieldName = FieldNames.FacebookID, Value = (string)friend[FBQueryResult.ID]
                        });
                        contact.FieldValues.Add(new FieldValue()
                        {
                            ItemID = contact.ID, FieldName = FieldNames.Sources, Value = Sources.Facebook
                        });
                        string jsonContact = JsonSerializer.Serialize(contact);

                        // store the serialized json contact in the value of a new NameValue item in possible contacts list
                        var nameValItem = new Item()
                        {
                            ID           = Guid.NewGuid(),
                            Name         = (string)friend[FBQueryResult.Name],
                            FolderID     = possibleContactsList.FolderID,
                            ParentID     = possibleContactsList.ID,
                            UserID       = user.ID,
                            ItemTypeID   = SystemItemTypes.NameValue,
                            Created      = now,
                            LastModified = now,
                            FieldValues  = new List <FieldValue>()
                        };
                        nameValItem.FieldValues.Add(new FieldValue()
                        {
                            FieldName = FieldNames.Value, ItemID = nameValItem.ID, Value = jsonContact
                        });
                        // add the FacebookID as a fieldvalue on the namevalue item which corresponds to the possible contact, for easier duplicate detection
                        nameValItem.FieldValues.Add(new FieldValue()
                        {
                            FieldName = FieldNames.FacebookID, ItemID = nameValItem.ID, Value = (string)friend[FBQueryResult.ID]
                        });

                        // add new possible subject to the storage and to the working list of possible contacts
                        userContext.Items.Add(nameValItem);
                        currentPossibleContacts.Add(nameValItem);
                    }
                }

                userContext.SaveChanges();
                TraceLog.TraceInfo(String.Format("Added {0} possible contacts to list", results.Count));
            }
            catch (Exception ex)
            {
                TraceLog.TraceException("Could not retrieve or create a new possible Contact", ex);
                return(false);
            }
            return(true);
        }
Beispiel #28
0
        static User LookupUserByID(Guid id, bool includeCredentials = false)
        {
            UserStorageContext storage = Storage.NewUserContext;

            return(storage.GetUser(id, includeCredentials));
        }
Beispiel #29
0
        public override MembershipUser CreateUser(string username, string password, string email, string passwordQuestion, string passwordAnswer, bool isApproved, object providerUserKey, out MembershipCreateStatus status)
        {
            status = MembershipCreateStatus.Success;
            UserStorageContext storage = Storage.NewUserContext;

            const string emailPattern = "^[a-z0-9_\\+-]+([\\.[a-z0-9_\\+-]+)*@[a-z0-9-]+(\\.[a-z0-9-]+)*\\.([a-z]{2,4})$";

            if (!Regex.IsMatch(email.ToLower(), emailPattern))
            {   // not valid email address
                status = MembershipCreateStatus.InvalidEmail;
                TraceLog.TraceInfo("Failed to create user account due to invalid email: " + email);
                return(null);
            }

            if (password.Length < MinRequiredPasswordLength)
            {   // not a valid password
                status = MembershipCreateStatus.InvalidPassword;
                TraceLog.TraceInfo("Failed to create user account due to invalid password: "******"Failed to create duplicate user account: " + username);
                return(null);
            }

            // create salt for each user and store hash of password
            string salt = CreateSalt(64);

            password = HashPassword(password, salt);
            Guid userID = (providerUserKey != null && providerUserKey is Guid) ? (Guid)providerUserKey : Guid.NewGuid();

            User user = new User()
            {
                ID         = userID,
                Name       = username.ToLower(),
                Email      = email.ToLower(),
                CreateDate = DateTime.UtcNow
            };
            UserCredential credentials = new UserCredential()
            {
                UserID         = user.ID,
                CredentialType = UserCredential.Password,
                AccessToken    = password,
                RenewalToken   = salt,
                LastModified   = user.CreateDate
            };

            user.UserCredentials = new List <UserCredential>()
            {
                credentials
            };
            storage.Users.Add(user);
            storage.SaveChanges();
            user   = storage.Users.Single <User>(u => u.Name == username);
            status = MembershipCreateStatus.Success;

            // Log creation of new user account
            TraceLog.TraceInfo("Created new user account: " + username);

            return(AsMembershipUser(user));
        }
Beispiel #30
0
 public UserDataModel(BaseResource resource)
 {
     this.storageContext = resource.StorageContext;
     this.currentUser    = resource.CurrentUser;
 }
Beispiel #31
0
        public static bool AddContactInfo(UserStorageContext userContext, Item item)
        {
            FieldValue fbfv = item.GetFieldValue(FieldNames.FacebookID);

            if (fbfv == null)
            {
                return(true);
            }

            User user = userContext.GetUser(item.UserID, true);

            if (user == null)
            {
                return(false);
            }

            // set up the FB API context
            FBGraphAPI     fbApi = new FBGraphAPI();
            UserCredential cred  = user.GetCredential(UserCredential.FacebookConsent);

            if (cred != null && cred.AccessToken != null)
            {
                fbApi.AccessToken = cred.AccessToken;
            }
            else
            {
                TraceLog.TraceError(TRACE_NO_FB_TOKEN);
                return(false);
            }

            // get or create an EntityRef in the UserFolder EntityRefs list
            var entityRefItem = userContext.UserFolder.GetEntityRef(user, item);

            if (entityRefItem == null)
            {
                TraceLog.TraceError(TRACE_NO_CONTACT_ENTITYREF);
                return(false);
            }

            try
            {   // get the Contact information from Facebook
                // using foreach because the Query API returns an IEnumerable, but there is only one result
                foreach (var contact in fbApi.Query(fbfv.Value, FBQueries.BasicInformation))
                {
                    item.GetFieldValue(FieldNames.Picture, true).Value = String.Format("https://graph.facebook.com/{0}/picture", fbfv.Value);
                    var birthday = (string)contact[FBQueryResult.Birthday];
                    if (birthday != null)
                    {
                        item.GetFieldValue(FieldNames.Birthday, true).Value = birthday;
                    }
                    var gender = (string)contact[FBQueryResult.Gender];
                    if (gender != null)
                    {
                        entityRefItem.GetFieldValue(FieldNames.Gender, true).Value = gender;
                    }
                }
                userContext.SaveChanges();
            }
            catch (Exception ex)
            {
                TraceLog.TraceException(TRACE_NO_SAVE_FBCONTACTINFO, ex);
                return(false);
            }

            return(true);
        }
Beispiel #32
0
 public UserDataModel(UserStorageContext storage, User user)
 {
     this.storageContext = storage;
     this.currentUser    = user;
 }
        /// <summary>
        /// Add a Contact to the possible contacts list
        /// </summary>
        /// <param name="userContext"></param>
        /// <param name="item"></param>
        /// <returns>false if errors were encountered, otherwise true</returns>
        public static bool AddContact(UserStorageContext userContext, Item item)
        {
            User user = userContext.GetUser(item.UserID);
            Item possibleContactsList = userContext.UserFolder.GetListForItemType(user, SystemItemTypes.Contact);

            if (possibleContactsList == null)
            {
                TraceLog.TraceError("Could not retrieve or create the possible contacts list");
                return(false);
            }

            try
            {
                // determine if a possible contact by this name already exists, and if so, skip adding it
                var nameValItem = userContext.Items.Include("FieldValues").FirstOrDefault(
                    ps => ps.UserID == user.ID && ps.FolderID == possibleContactsList.FolderID &&
                    ps.Name == item.Name && ps.ParentID == possibleContactsList.ID && ps.ItemTypeID == SystemItemTypes.NameValue);

                if (nameValItem == null)
                {
                    // store the serialized contact in the value of a new NameValue item on the PossibleContacts list
                    string jsonContact = JsonSerializer.Serialize(item);

                    Guid     id  = Guid.NewGuid();
                    DateTime now = DateTime.UtcNow;
                    nameValItem = new Item()
                    {
                        ID           = id,
                        Name         = item.Name,
                        FolderID     = possibleContactsList.FolderID,
                        ParentID     = possibleContactsList.ID,
                        UserID       = user.ID,
                        ItemTypeID   = SystemItemTypes.NameValue,
                        Created      = now,
                        LastModified = now,
                        FieldValues  = new List <FieldValue>()
                        {
                            new FieldValue()
                            {
                                FieldName = FieldNames.Value, ItemID = id, Value = jsonContact
                            }
                        }
                    };

                    // add the new possible contact to the DB
                    userContext.Items.Add(nameValItem);
                }

                // store a reference fieldvalue on the namevalue item to designate that this possible contact relates to an existing Contact
                nameValItem.GetFieldValue(FieldNames.EntityRef, true).Value  = item.ID.ToString();
                nameValItem.GetFieldValue(FieldNames.EntityType, true).Value = EntityTypes.Item;

                // store the updated possible contact in the DB
                userContext.SaveChanges();
            }
            catch (Exception ex)
            {
                TraceLog.TraceException("Could not create a new PossibleContact", ex);
                return(false);
            }

            return(true);
        }
 public AccountController(IEncryptor encryptor, UserStorageContext userStorage)
 {
     this.encryptor   = encryptor;
     this.userStorage = userStorage;
 }
Beispiel #35
0
 public UserStorageService(UserStorageContext dbContext, ILogger <UserStorageService> logger)
 {
     _logger    = logger;
     _dbContext = dbContext;
 }
Beispiel #36
0
        public static bool ImportFriendsAsPossibleContacts(User user, UserStorageContext userContext)
        {
            // set up the FB API context
            FBGraphAPI fbApi = new FBGraphAPI();
            UserCredential cred = user.GetCredential(UserCredential.FacebookConsent);
            if (cred != null && cred.AccessToken != null)
            {
                fbApi.AccessToken = cred.AccessToken;
            }
            else
            {
                TraceLog.TraceError(TRACE_NO_FB_TOKEN);
                return false;
            }

            // get or create the list for Contact item types in the UserFolder
            Item possibleContactsList = userContext.UserFolder.GetListForItemType(user, SystemItemTypes.Contact);
            if (possibleContactsList == null)
            {
                TraceLog.TraceError("Could not retrieve or create the possible contacts list");
                return false;
            }

            // get the current list of all possible contacts for this user
            var currentPossibleContacts = userContext.Items.Include("FieldValues").Where(ps => ps.UserID == user.ID && ps.FolderID == possibleContactsList.FolderID &&
                ps.ParentID == possibleContactsList.ID && ps.ItemTypeID == SystemItemTypes.NameValue &&
                ps.FieldValues.Any(fv => fv.FieldName == FieldNames.FacebookID)).ToList();

            // get the current list of all Items that are Contacts for this user
            var currentContacts = userContext.Items.Include("FieldValues").
                        Where(c => c.UserID == user.ID && c.ItemTypeID == SystemItemTypes.Contact).ToList();

            // get all the user's friends and add them as serialized contacts to the possible contacts list
            DateTime now = DateTime.UtcNow;
            try
            {
                var results = fbApi.Query("me", FBQueries.Friends).ToList();
                TraceLog.TraceInfo(String.Format("Found {0} Facebook friends", results.Count));
                foreach (var friend in results)
                {
                    // check if a possible contact by this name and with this FBID already exists - and if so, skip it
                    if (currentPossibleContacts.Any(
                            ps => ps.Name == (string)friend[FBQueryResult.Name] &&
                            ps.FieldValues.Any(fv => fv.FieldName == FieldNames.FacebookID && fv.Value == (string)friend[FBQueryResult.ID])))
                        continue;

                    bool process = true;

                    // check if a contact by this name already exists
                    var existingContacts = currentContacts.Where(c => c.Name == (string)friend[FBQueryResult.Name]).ToList();
                    foreach (var existingContact in existingContacts)
                    {
                        var fbFV = existingContact.GetFieldValue(FieldNames.FacebookID, true);
                        if (fbFV.Value == null)
                        {
                            // contact with this name exists but no FacebookID, assume same and set the FacebookID
                            fbFV.Value = (string)friend[FBQueryResult.ID];
                            var sourcesFV = existingContact.GetFieldValue(FieldNames.Sources, true);
                            sourcesFV.Value = string.IsNullOrEmpty(sourcesFV.Value) ? Sources.Facebook : string.Concat(sourcesFV.Value, ",", Sources.Facebook);
                            process = false;
                            break;
                        }
                        if (fbFV.Value == (string)friend[FBQueryResult.ID])
                        {   // FacebookIDs are same, definitely a duplicate, do not add
                            process = false;
                            break;
                        }
                        // contact with same name was found but had a different FacebookID, add as a new contact
                    }

                    // add contact if not a duplicate
                    if (process)
                    {
                        var contact = new Item()
                        {
                            ID = Guid.NewGuid(),
                            Name = (string)friend[FBQueryResult.Name],
                            UserID = user.ID,
                            ItemTypeID = SystemItemTypes.Contact,
                            FieldValues = new List<FieldValue>(),
                        };
                        contact.FieldValues.Add(new FieldValue() { ItemID = contact.ID, FieldName = FieldNames.FacebookID, Value = (string)friend[FBQueryResult.ID] });
                        contact.FieldValues.Add(new FieldValue() { ItemID = contact.ID, FieldName = FieldNames.Sources, Value = Sources.Facebook });
                        string jsonContact = JsonSerializer.Serialize(contact);

                        // store the serialized json contact in the value of a new NameValue item in possible contacts list
                        var nameValItem = new Item()
                        {
                            ID = Guid.NewGuid(),
                            Name = (string)friend[FBQueryResult.Name],
                            FolderID = possibleContactsList.FolderID,
                            ParentID = possibleContactsList.ID,
                            UserID = user.ID,
                            ItemTypeID = SystemItemTypes.NameValue,
                            Created = now,
                            LastModified = now,
                            FieldValues = new List<FieldValue>()
                        };
                        nameValItem.FieldValues.Add(new FieldValue() { FieldName = FieldNames.Value, ItemID = nameValItem.ID, Value = jsonContact });
                        // add the FacebookID as a fieldvalue on the namevalue item which corresponds to the possible contact, for easier duplicate detection
                        nameValItem.FieldValues.Add(new FieldValue() { FieldName = FieldNames.FacebookID, ItemID = nameValItem.ID, Value = (string)friend[FBQueryResult.ID] });

                        // add new possible subject to the storage and to the working list of possible contacts
                        userContext.Items.Add(nameValItem);
                        currentPossibleContacts.Add(nameValItem);
                    }
                }

                userContext.SaveChanges();
                TraceLog.TraceInfo(String.Format("Added {0} possible contacts to list", results.Count));
            }
            catch (Exception ex)
            {
                TraceLog.TraceException("Could not retrieve or create a new possible Contact", ex);
                return false;
            }
            return true;
        }