public HttpResponseMessage CheckAuthenicationSession(int siteId, string code) { var response = new HttpResponseMessage(); var authCheckResponse = new AuthCodeCheckResponse(); var deviceData = JsonConvert.DeserializeObject <DeviceData>(this.Request.GetHeader("X-Rock-DeviceData")); var rockContext = new RockContext(); var remoteAuthenticationSessionService = new RemoteAuthenticationSessionService(rockContext); // Get client Ip address var clientIp = GetClientIp(Request); var expireDateTime = RockDateTime.Now.AddMinutes(_codeReusePeriodInMinutes); // Check for validated account var validatedSession = remoteAuthenticationSessionService.Queryable() .Include(s => s.AuthorizedPersonAlias.Person) .Where(s => s.Code == code && s.SiteId == siteId && s.SessionStartDateTime < expireDateTime && s.AuthorizedPersonAliasId.HasValue && s.DeviceUniqueIdentifier == deviceData.DeviceIdentifier && s.ClientIpAddress == clientIp) .OrderByDescending(s => s.SessionStartDateTime) .FirstOrDefault(); if (validatedSession != null) { // Mark the auth session as ended validatedSession.SessionEndDateTime = RockDateTime.Now; rockContext.SaveChanges(); authCheckResponse.CurrentPerson = TvHelper.GetTvPerson(validatedSession.AuthorizedPersonAlias.Person); authCheckResponse.IsAuthenciated = true; // Link personal device var tvDeviceTypeValueId = DefinedValueCache.Get(SystemGuid.DefinedValue.PERSONAL_DEVICE_TYPE_TV).Id; var personalDeviceService = new PersonalDeviceService(rockContext); var personalDevice = personalDeviceService.Queryable() .Where(a => a.DeviceUniqueIdentifier == deviceData.DeviceIdentifier && a.PersonalDeviceTypeValueId == tvDeviceTypeValueId && a.SiteId == siteId) .FirstOrDefault(); if (personalDevice != null) { personalDevice.PersonAliasId = validatedSession.AuthorizedPersonAliasId; } } else { authCheckResponse.IsAuthenciated = false; } rockContext.SaveChanges(); // Return response.Content = new StringContent(authCheckResponse.ToJson(), System.Text.Encoding.UTF8, "application/json"); response.StatusCode = HttpStatusCode.OK; return(response); }
/// <summary> /// Attempts the authentication. /// </summary> private void AttemptAuthentication(string authCode) { pnlAuthenticate.Visible = false; pnlSuccess.Visible = true; var codeExpirationDuration = GetAttributeValue(AttributeKey.CodeExpirationDuration).AsInteger(); var codeExpirationDateTime = RockDateTime.Now.AddMinutes(codeExpirationDuration * -1); // Get site var siteId = GetAttributeValue(AttributeKey.Site).AsIntegerOrNull(); if (siteId.HasValue) { var site = SiteCache.Get(siteId.Value); siteId = site.Id; } // Get matching remote authenication record var rockContext = new RockContext(); var remoteAuthenticationService = new RemoteAuthenticationSessionService(rockContext); // Create a fallback date to eliminate very old sessions. We want to be able to tell someone // that the code they have has expired so we can't use the expiration date, we need a date older // than that. var expirationWindowDate = codeExpirationDateTime.AddHours(-2); var authSession = remoteAuthenticationService.Queryable() .Where(s => s.SiteId == siteId && s.Code == authCode && s.AuthorizedPersonAliasId == null && s.SessionStartDateTime > expirationWindowDate) .FirstOrDefault(); // Check for code that does not exist if (authSession == null) { nbAuthenticationMessages.Text = "The code provided is not valid. Please confirm that you have correctly entered the code."; nbAuthenticationMessages.NotificationBoxType = NotificationBoxType.Warning; nbAuthenticationMessages.Visible = true; return; } // Check for expired session if (authSession.SessionStartDateTime < codeExpirationDateTime) { nbAuthenticationMessages.Text = "The code you provided has expired. Please create a new new code and try again."; nbAuthenticationMessages.NotificationBoxType = NotificationBoxType.Warning; nbAuthenticationMessages.Visible = true; return; } // Process authentication authSession.AuthorizedPersonAliasId = CurrentPersonAliasId; authSession.SessionAuthenticatedDateTime = RockDateTime.Now; authSession.AuthenticationIpAddress = RockPage.GetClientIpAddress(); rockContext.SaveChanges(); // Show success message pnlAuthenticate.Visible = false; pnlSuccess.Visible = true; var mergeFields = Rock.Lava.LavaHelper.GetCommonMergeFields(this.RockPage, null, new Rock.Lava.CommonMergeFieldsOptions { GetLegacyGlobalMergeFields = false }); lSuccessContent.Text = GetAttributeValue(AttributeKey.SuccessMessage).ResolveMergeFields(mergeFields); }
public HttpResponseMessage StartAuthenicationSession(int siteId) { var response = new HttpResponseMessage(); var authCode = string.Empty; var deviceData = JsonConvert.DeserializeObject <DeviceData>(this.Request.GetHeader("X-Rock-DeviceData")); var site = SiteCache.Get(siteId); var authGenerationCount = 0; var maxAuthGenerationAttempts = 50; var rockContext = new RockContext(); var remoteAuthenticationSessionService = new RemoteAuthenticationSessionService(rockContext); // Get client IP var clientIp = GetClientIp(Request); var expireDateTime = RockDateTime.Now.AddMinutes(_codeReusePeriodInMinutes); // Get random code while (authCode == string.Empty && authGenerationCount < maxAuthGenerationAttempts) { authCode = RandomString(6); // Remove characters that could be confusing for clarity authCode.Replace('0', '2'); authCode.Replace('O', 'P'); // Check that the code is not already being used in the last 5 days var codeReuseWindow = RockDateTime.Now.AddDays(-5); var usedCodes = remoteAuthenticationSessionService.Queryable() .Where(s => s.Code == authCode && s.SessionStartDateTime > expireDateTime) .Any(); // If matching code was found try again if (usedCodes) { authCode = string.Empty; } // Remove bad sequences foreach (var badSequence in AttendanceCodeService.NoGood) { if (authCode.Contains(badSequence)) { authCode = string.Empty; } } authGenerationCount++; } // Check that we were able to generate an auth code if (authGenerationCount >= maxAuthGenerationAttempts) { response.StatusCode = HttpStatusCode.InternalServerError; return(response); } // Create authenication session var remoteSession = new RemoteAuthenticationSession(); remoteAuthenticationSessionService.Add(remoteSession); remoteSession.SiteId = siteId; remoteSession.ClientIpAddress = clientIp; remoteSession.Code = authCode; remoteSession.SessionStartDateTime = ( DateTime )RockDateTime.Now; remoteSession.DeviceUniqueIdentifier = deviceData.DeviceIdentifier; rockContext.SaveChanges(); var authReturn = new AuthCodeResponse(); authReturn.Code = authCode; authReturn.ExpireDateTime = expireDateTime; var loginPageReference = site.LoginPageReference; loginPageReference.Parameters.AddOrReplace("AuthCode", authCode); var qrData = HttpUtility.UrlEncode($"{GlobalAttributesCache.Value( "PublicApplicationRoot" ).TrimEnd( '/' )}{loginPageReference.BuildUrl()}"); authReturn.AuthenticationUrlQrCode = $"{GlobalAttributesCache.Value( "PublicApplicationRoot" )}GetQRCode.ashx?data={qrData}&outputType=png"; response.Content = new StringContent(authReturn.ToJson(), System.Text.Encoding.UTF8, "application/json"); response.StatusCode = HttpStatusCode.OK; return(response); }