Example #1
0
        public IHttpActionResult GetLaunchPacket()
        {
            // Read site Id from the request header
            var siteId = this.Request.GetHeader("X-Rock-App-Id").AsIntegerOrNull();

            // Get device data from the request header
            // Get device data
            var deviceData = JsonConvert.DeserializeObject <DeviceData>(this.Request.GetHeader("X-Rock-DeviceData"));

            if (deviceData == null)
            {
                StatusCode(HttpStatusCode.InternalServerError);
            }

            if (!siteId.HasValue)
            {
                return(NotFound());
            }

            var site = SiteCache.Get(siteId.Value);

            // If the site was not found then return 404
            if (site == null)
            {
                return(NotFound());
            }

            // Return the launch packet
            try
            {
                var rockContext = new RockContext();
                var person      = GetPerson(rockContext);

                var launchPacket = new AppleLaunchPacket();
                launchPacket.EnablePageViews = site.EnablePageViews;

                if (person != null)
                {
                    var principal = ControllerContext.Request.GetUserPrincipal();

                    launchPacket.CurrentPerson           = TvHelper.GetTvPerson(person);
                    launchPacket.CurrentPerson.AuthToken = TvHelper.GetAuthenticationTokenFromUsername(principal.Identity.Name);

                    UserLoginService.UpdateLastLogin(principal.Identity.Name);
                }

                // Get or create the 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 == site.Id)
                                            .FirstOrDefault();

                if (personalDevice == null)
                {
                    personalDevice = new PersonalDevice
                    {
                        DeviceUniqueIdentifier    = deviceData.DeviceIdentifier,
                        PersonalDeviceTypeValueId = tvDeviceTypeValueId,
                        SiteId               = site.Id,
                        PersonAliasId        = person?.PrimaryAliasId,
                        NotificationsEnabled = true,
                        Manufacturer         = deviceData.Manufacturer,
                        Model            = deviceData.Model,
                        Name             = deviceData.Name,
                        IsActive         = true,
                        LastSeenDateTime = RockDateTime.Now,
                        DeviceVersion    = deviceData.Version
                    };

                    personalDeviceService.Add(personalDevice);
                    rockContext.SaveChanges();
                }
                else
                {
                    // A change is determined as one of the following:
                    // 1) A change in Name, Manufacturer, Model, or NotificationsEnabled.
                    // 2) Device not being active.
                    // 3) Not seen in 24 hours.
                    // 4) Signed in with a different person.
                    var hasDeviceChanged = !personalDevice.IsActive ||
                                           personalDevice.Name != deviceData.Name ||
                                           personalDevice.Manufacturer != deviceData.Manufacturer ||
                                           personalDevice.Model != deviceData.Model ||
                                           !personalDevice.LastSeenDateTime.HasValue ||
                                           personalDevice.LastSeenDateTime.Value.AddDays(1) < RockDateTime.Now ||
                                           (person != null && personalDevice.PersonAliasId != person.PrimaryAliasId);

                    if (hasDeviceChanged)
                    {
                        personalDevice.IsActive         = true;
                        personalDevice.Manufacturer     = deviceData.Manufacturer;
                        personalDevice.Model            = deviceData.Model;
                        personalDevice.Name             = deviceData.Name;
                        personalDevice.LastSeenDateTime = RockDateTime.Now;

                        // Update the person tied to the device, but never blank it out.
                        if (person != null && personalDevice.PersonAliasId != person.PrimaryAliasId)
                        {
                            personalDevice.PersonAliasId = person.PrimaryAliasId;
                        }

                        rockContext.SaveChanges();
                    }
                }

                launchPacket.PersonalDeviceGuid = personalDevice.Guid;
                launchPacket.HomepageGuid       = site.DefaultPage.Guid;

                launchPacket.RockVersion = VersionInfo.VersionInfo.GetRockProductVersionNumber();

                return(Ok(launchPacket));
            }
            catch (Exception)
            {
                // Ooops...
                return(StatusCode(HttpStatusCode.InternalServerError));
            }
        }
Example #2
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 #3
0
        public IHttpActionResult PostInteractions([FromBody] List <TvInteractionSession> sessions, Guid?personalDeviceGuid = null)
        {
            var person    = GetPerson();
            var ipAddress = System.Web.HttpContext.Current?.Request?.UserHostAddress;

            using (var rockContext = new RockContext())
            {
                var interactionChannelService   = new InteractionChannelService(rockContext);
                var interactionComponentService = new InteractionComponentService(rockContext);
                var interactionSessionService   = new InteractionSessionService(rockContext);
                var interactionService          = new InteractionService(rockContext);
                var userLoginService            = new UserLoginService(rockContext);
                var channelMediumTypeValue      = DefinedValueCache.Get(Rock.SystemGuid.DefinedValue.INTERACTIONCHANNELTYPE_WEBSITE);
                var pageEntityTypeId            = EntityTypeCache.Get(typeof(Rock.Model.Page)).Id;

                // Check to see if we have a site and the API key is valid.
                if (TvHelper.GetCurrentApplicationSite() == null)
                {
                    return(StatusCode(System.Net.HttpStatusCode.Forbidden));
                }

                // Get the personal device identifier if they provided it's unique identifier.
                int?personalDeviceId = null;
                if (personalDeviceGuid.HasValue)
                {
                    personalDeviceId = new PersonalDeviceService(rockContext).GetId(personalDeviceGuid.Value);
                }

                // Create a quick way to cache data since we have to loop twice.
                var interactionComponentLookup = new Dictionary <string, int>();

                //
                // Helper method to get a cache key for looking up the component Id.
                //
                string GetComponentCacheKey(TvInteraction mi)
                {
                    return($"{mi.AppId}:{mi.PageGuid}:{mi.ChannelGuid}:{mi.ChannelId}:{mi.ComponentId}:{mi.ComponentName}");
                }

                //
                // Interactions Components will now try to load from cache which
                // causes problems if we are inside a transaction. So first loop through
                // everything and make sure all our components and channels exist.
                //
                var prePassInteractions = sessions.SelectMany(a => a.Interactions)
                                          .DistinctBy(a => GetComponentCacheKey(a));

                //
                // It's safe to do this pre-pass outside the transaction since we are just creating
                // the channels and components (if necessary), which is going to have to be done at
                // at some point no matter what.
                //
                foreach (var mobileInteraction in prePassInteractions)
                {
                    //
                    // Lookup the interaction channel, and create it if it doesn't exist
                    //
                    if (mobileInteraction.AppId.HasValue && mobileInteraction.PageGuid.HasValue)
                    {
                        var site = SiteCache.Get(mobileInteraction.AppId.Value);
                        var page = PageCache.Get(mobileInteraction.PageGuid.Value);

                        if (site == null || page == null)
                        {
                            continue;
                        }

                        //
                        // Try to find an existing interaction channel.
                        //
                        var interactionChannelId = InteractionChannelCache.GetChannelIdByTypeIdAndEntityId(channelMediumTypeValue.Id, site.Id, site.Name, pageEntityTypeId, null);

                        //
                        // Get an existing or create a new component.
                        //
                        var interactionComponentId = InteractionComponentCache.GetComponentIdByChannelIdAndEntityId(interactionChannelId, page.Id, page.InternalName);

                        interactionComponentLookup.AddOrReplace(GetComponentCacheKey(mobileInteraction), interactionComponentId);
                    }
                    else if (mobileInteraction.ChannelId.HasValue || mobileInteraction.ChannelGuid.HasValue)
                    {
                        int?interactionChannelId = null;

                        if (mobileInteraction.ChannelId.HasValue)
                        {
                            interactionChannelId = mobileInteraction.ChannelId.Value;
                        }
                        else if (mobileInteraction.ChannelGuid.HasValue)
                        {
                            interactionChannelId = InteractionChannelCache.Get(mobileInteraction.ChannelGuid.Value)?.Id;
                        }

                        if (interactionChannelId.HasValue)
                        {
                            if (mobileInteraction.ComponentId.HasValue)
                            {
                                // Use the provided component identifier.
                                interactionComponentLookup.AddOrReplace(GetComponentCacheKey(mobileInteraction), mobileInteraction.ComponentId.Value);
                            }
                            else if (mobileInteraction.ComponentName.IsNotNullOrWhiteSpace())
                            {
                                int interactionComponentId;

                                // Get or create a new component with the details we have.
                                if (mobileInteraction.ComponentEntityId.HasValue)
                                {
                                    interactionComponentId = InteractionComponentCache.GetComponentIdByChannelIdAndEntityId(interactionChannelId.Value, mobileInteraction.ComponentEntityId, mobileInteraction.ComponentName);
                                }
                                else
                                {
                                    var interactionComponent = interactionComponentService.GetComponentByComponentName(interactionChannelId.Value, mobileInteraction.ComponentName);

                                    rockContext.SaveChanges();

                                    interactionComponentId = interactionComponent.Id;
                                }

                                interactionComponentLookup.AddOrReplace(GetComponentCacheKey(mobileInteraction), interactionComponentId);
                            }
                        }
                    }
                }

                //
                // Now wrap the actual interaction creation inside a transaction. We should
                // probably move this so it uses the InteractionTransaction class for better
                // performance. This is so we can inform the client that either everything
                // saved or that nothing saved. No partial saves here.
                //
                rockContext.WrapTransaction(() =>
                {
                    foreach (var tvSession in sessions)
                    {
                        var interactionGuids         = tvSession.Interactions.Select(i => i.Guid).ToList();
                        var existingInteractionGuids = interactionService.Queryable()
                                                       .Where(i => interactionGuids.Contains(i.Guid))
                                                       .Select(i => i.Guid)
                                                       .ToList();

                        //
                        // Loop through all interactions that don't already exist and add each one.
                        //
                        foreach (var tvInteraction in tvSession.Interactions.Where(i => !existingInteractionGuids.Contains(i.Guid)))
                        {
                            string cacheKey = GetComponentCacheKey(tvInteraction);

                            if (!interactionComponentLookup.ContainsKey(cacheKey))
                            {
                                // Shouldn't happen, but just in case.
                                continue;
                            }

                            var interactionComponentId = interactionComponentLookup[cacheKey];

                            //
                            // Add the interaction
                            //
                            var interaction = interactionService.CreateInteraction(interactionComponentId,
                                                                                   tvInteraction.EntityId,
                                                                                   tvInteraction.Operation,
                                                                                   tvInteraction.Summary,
                                                                                   tvInteraction.Data,
                                                                                   person?.PrimaryAliasId,
                                                                                   RockDateTime.ConvertLocalDateTimeToRockDateTime(tvInteraction.DateTime.LocalDateTime),
                                                                                   tvSession.Application,
                                                                                   tvSession.OperatingSystem,
                                                                                   tvSession.ClientType,
                                                                                   null,
                                                                                   ipAddress,
                                                                                   tvSession.Guid);

                            interaction.Guid                   = tvInteraction.Guid;
                            interaction.PersonalDeviceId       = personalDeviceId;
                            interaction.RelatedEntityTypeId    = tvInteraction.RelatedEntityTypeId;
                            interaction.RelatedEntityId        = tvInteraction.RelatedEntityId;
                            interaction.ChannelCustom1         = tvInteraction.ChannelCustom1;
                            interaction.ChannelCustom2         = tvInteraction.ChannelCustom2;
                            interaction.ChannelCustomIndexed1  = tvInteraction.ChannelCustomIndexed1;
                            interaction.InteractionTimeToServe = tvInteraction.InteractionTimeToServe;

                            interactionService.Add(interaction);
                        }
                    }

                    rockContext.SaveChanges();
                });
            }

            return(Ok());
        }