public static Task SendEmailConfirmationAsync(this IMessagingApi emailSender, string email, string link)
 {
     return(emailSender.SendEmail(email, "Confirm your email",
                                  $"Please confirm your account by clicking this link: <a href='{HtmlEncoder.Default.Encode(link)}'>link</a>"));
 }
        public async Task <IActionResult> Finish(string quizId, PresentExamModel formModel, [FromServices] IConfiguration configuration, [FromServices] IMessagingApi messaging, [FromServices] IDatabaseApi database)
        {
            var quiz = store.Quizzes.FirstOrDefault(f => f.Id.Equals(quizId, StringComparison.OrdinalIgnoreCase) || f.Title.Replace(" ", "-").Equals(quizId, StringComparison.OrdinalIgnoreCase));

            if (quiz == null)
            {
                logger.LogWarning("Can't find exam with id " + quizId);
                return(View("Error", new ErrorViewModel {
                    RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier
                }));
            }

            if (!ModelState.IsValid)
            {
                return(BadRequest(ModelState));
            }

            var numWrong  = 0;
            var incorrect = new List <string>();

            foreach (var question in quiz.Questions)
            {
                if (Request.Form.TryGetValue(question.Id + "[]", out StringValues postedAnswer))
                {
                    // user answered the question
                    var expected = question.Answers.Where(f => f.Correct).Select(f => f.Id.ToLowerInvariant()).ToArray();
                    var actual   = postedAnswer.Select(f => f.ToLowerInvariant()).ToArray();

                    if (expected.Length != actual.Length)
                    {
                        incorrect.Add(question.Text);
                        numWrong++;
                        continue;
                    }

                    for (int i = 0; i < expected.Length; i++)
                    {
                        if (expected[i] != actual[i])
                        {
                            incorrect.Add(question.Text);
                            numWrong++;
                            continue;
                        }
                    }
                }
                else
                {
                    incorrect.Add(question.Text);
                    // user did not answer the question
                    numWrong++;
                }
            }

            var model = new TestResultsModel
            {
                Id       = new Guid(Request.Form["Id"].Single()),
                Name     = User.FindFirst("name")?.Value ?? Request.Form["Name"],
                Email    = User.FindFirst("email")?.Value ?? Request.Form["Email"],
                MemberId = User.FindFirst("memberId")?.Value,

                Title  = quiz.Title,
                QuizId = quiz.Id,

                Score    = quiz.Questions.Count - numWrong,
                Possible = quiz.Questions.Count,

                Completed = DateTimeOffset.Now,
                Incorrect = incorrect
            };

            var passing = configuration.GetValue <float?>("passing_score") ?? 80;

            model.Percentage = model.Score / (float)model.Possible * 100.0f;
            model.Passed     = model.Percentage >= passing;

            model.Duration = model.Completed - DateTimeOffset.Parse(Request.Form["Started"].Single());

            if (model.Passed)
            {
                var cert = await certificateStore.AddCertificate(new CertificateEntity
                {
                    RowKey    = model.Id.ToString().ToLowerInvariant(),
                    Completed = model.Completed,
                    Name      = model.Name,
                    Title     = model.Title
                });

                // Send email to user
                string message = $"Full Name: {model.Name}<br/>Email: {model.Email}<br/><br/>Course: {model.Title}<br/>Results: {model.Score} out of {model.Possible}.<br/><br/>A certificate of completion is attached.<br/><br/><br/>--<br/>KCSARA Training Committee<br/>[email protected]";
                await messaging.SendEmail(model.Email, "KCSARA Online Exam Results", message, new List <MessageAttachment>
                {
                    new MessageAttachment {
                        Base64 = Convert.ToBase64String(cert.Data), FileName = cert.FileName, MimeType = cert.MimeType
                    }
                });

                if (Guid.TryParse(quiz.RecordsId, out Guid courseId) && Guid.TryParse(model.MemberId, out Guid memberId))
                {
                    var record = await database.CreateTrainingRecord(new TrainingRecord
                    {
                        Completed = model.Completed,
                        Course    = new NameIdPair {
                            Id = courseId
                        },
                        Member = new NameIdPair {
                            Id = memberId
                        },
                        Comments = $"{configuration["siteRoot"]?.TrimEnd('/') ?? "https://exams.kcsara.org"}/certificate/{model.Id}"
                    });
                }
            }

            return(View(model));
        }
Esempio n. 3
0
        public async Task <IActionResult> ExternalLoginConfirmation(ExternalLoginViewModel model, string returnUrl = null)
        {
            ViewData["ReturnUrl"] = returnUrl;
            if (ModelState.IsValid)
            {
                // Get the information about the user from the external login provider
                var info = await signin.GetExternalLoginInfoAsync();

                if (info == null)
                {
                    throw new ApplicationException("Error loading external login information during confirmation.");
                }

                ViewData["LoginProvider"] = info.LoginProvider;

                IdentityResult      result;
                List <RemoteMember> members = new List <RemoteMember>();
                bool foundPhone             = false;
                if (!string.IsNullOrWhiteSpace(model.Phone))
                {
                    members = await remoteMembers.FindByPhone(model.Phone);
                }
                if (members.Count == 1)
                {
                    foundPhone = true;
                }
                else if (!string.IsNullOrWhiteSpace(model.Email))
                {
                    members = await remoteMembers.FindByEmail(model.Email);
                }

                if (members.Count != 1)
                {
                    result = IdentityResult.Failed(new IdentityError {
                        Code = "NotMemberEmail", Description = "Unable to find member."
                    });
                }
                else
                {
                    var codeRow = await db.ExternalLoginCodes.FindAsync(info.ProviderKey);

                    if (codeRow == null)
                    {
                        codeRow = new ExternalLoginCode {
                            LoginSubject = info.ProviderKey
                        };
                        db.ExternalLoginCodes.Add(codeRow);
                    }
                    codeRow.MemberId   = members[0].Id;
                    codeRow.ExpiresUtc = DateTime.UtcNow.AddMinutes(10);
                    codeRow.Code       = new Random().Next(1000000).ToString("000000");
                    await db.SaveChangesAsync();

                    if (foundPhone)
                    {
                        await messaging.SendText(model.Phone, "Your verification code: " + codeRow.Code);
                    }
                    else
                    {
                        await messaging.SendEmail(model.Email, "Verification Code", "Your verificaton code: " + codeRow.Code);
                    }

                    return(View("ExternalVerify"));
                }
                AddErrors(result);
            }

            return(View(nameof(ExternalLogin), model));
        }
Esempio n. 4
0
        public async Task <IActionResult> TestEmail(string to, [FromServices] IMessagingApi messaging)
        {
            await messaging.SendEmail(to, "Test email from auth service", "This is a test mail. I hope it made it through");

            return(Content("OK"));
        }