Example #1
0
        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);
        }
Example #2
0
        /// <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);
        }
Example #3
0
        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);
        }