private static bool ValidateToken(string encodedToken, string userEmail, User.AppType appType)
        {
            JwtSecurityToken token = new JwtSecurityToken(encodedToken);

            if (token.Claims == null)
            {
                return false;
            }

            Dictionary<string, string> claimVals = token.Claims.ToDictionary(x => x.Type, x => x.Value);

            if (claimVals["iss"] != "accounts.google.com" ||
                claimVals["azp"] != ConfidentialData.GoogleClientIdDictionary[appType] ||
                claimVals["aud"] != ConfidentialData.GoogleWebAppClientId ||
                claimVals["email"] != userEmail)
            {
                return false;
            }

            // Check token hasn't expired
            DateTime expirationDate = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
            expirationDate = expirationDate.AddSeconds(int.Parse(claimVals["exp"]));

            // This is a valid token for this app if it's still in date!
            return expirationDate.ToLocalTime() >= DateTime.Now;
        }
        /// <summary>
        /// Checks if the user has completed an assessment today, returning one if not
        /// </summary>
        /// <returns></returns>
        private static async Task<ParticipantActivity> GetAssessmentIfNeeded(CrowdContext db, User user)
        {
            bool existing = false;

            if (user.LastAssessment != null)
            {
                ParticipantActivity act = await db.ParticipantActivities.FindAsync(user.LastAssessment.ParticipantActivityId);
                if (act != null && act.AppType == user.App) existing = true;
            }

            if (existing)
            {
                // We want the user to complete the same assessment each time, at most once a day
                ParticipantResult recentUpload = await (from upload in db.ParticipantResults
                    where upload.User.Email == user.Email &&
                          upload.IsAssessment &&
                          ((int)upload.ParticipantActivity.AppType == (int)user.App ||
                          (int)upload.ParticipantActivity.AppType == (int)Crowd.Model.Data.User.AppType.None)
                    orderby upload.UploadedAt descending
                    select upload).FirstOrDefaultAsync();

                if(recentUpload == null) return null;

                TimeSpan span = DateTime.Now - recentUpload.UploadedAt;

                if (span.Days >= 1)
                {
                    if (recentUpload.ParticipantActivity != null)
                    {
                        return recentUpload.ParticipantActivity;
                    }

                    return await db.ParticipantActivities.FindAsync(recentUpload.ParticipantActivityId);
                }
            }
            else
            {
                // User has yet to complete an assessment - choose a random one
                ParticipantActivity[] assessments = await (
                    from act in db.ParticipantActivities
                    where act.AssessmentTasks.Count >= 1 &&
                          ((int)act.AppType == (int)user.App ||
                          (int)act.AppType == (int)Crowd.Model.Data.User.AppType.None)
                    select act).ToArrayAsync();

                if (assessments.Length >= 1)
                {
                    Random rand = new Random();
                    return assessments[rand.Next(0, assessments.Length - 1)];
                }
            }
            return null;
        }
        private static async Task<ParticipantActivity> GetRandomScenario(CrowdContext db, User user)
        {
            ParticipantActivity[] acts = await (from act in db.ParticipantActivities
                where (act.AppType == Crowd.Model.Data.User.AppType.None || act.AppType == user.App) &&
                      act.ParticipantTasks.Count >= 1
                select act).ToArrayAsync();

            if (acts.Length >= 1)
            {
                Random rand = new Random();
                return acts[rand.Next(0, acts.Length - 1)];
            }
            return null;
        }
 public ServiceUser(User baseUser)
 {
     Email = baseUser.Email;
     Key = baseUser.Key;
     Name = baseUser.Name;
     Nickname = baseUser.Nickname;
     Avatar = baseUser.Avatar;
     IsAdmin = baseUser.IsAdmin;
     SubscribedCategories = baseUser.SubscribedCategories.ToList();
     Submissions = baseUser.Submissions.ToList();
     LastAssessment = baseUser.LastAssessment;
     FeedItems = baseUser.FeedItems.ToList();
     DismissedPublicFeedItems = baseUser.DismissedPublicFeedItems.ToList();
     App = baseUser.App;
 }
        private static async Task<int?> GetMostRecentJobId(CrowdContext db, User user)
        {
            ParticipantResult mostRecent = await db.ParticipantResults.Where(res => res.User.Email == user.Email &&
                        ((int)res.ParticipantActivity.AppType == (int)user.App ||
                                        (int)res.ParticipantActivity.AppType == (int)Crowd.Model.Data.User.AppType.None)).OrderByDescending(res => res.UploadedAt).FirstOrDefaultAsync();

            if (mostRecent == null)
            {
                return null;
            }
            else
            {
                return mostRecent.CrowdJobId;
            }

        }