Esempio n. 1
0
        public async Task <ActionResult <PlatformUserConnectionStateViewModel> > UpdateUserPlatformConnectionState(
            [FromBody, Required] UserPlatformConnectionStateUpdateModel model, CancellationToken cancellationToken)
        {
            var uniqueUserIdentifier = _httpContextAccessor.HttpContext.User.Identity.Name;

            using var session = _documentStore.OpenAsyncSession();
            var user = await _userManager.GetUserByUniqueIdentifier(uniqueUserIdentifier, session, cancellationToken);

            // update state
            foreach (var platformConnectionStateUpdate in model.PlatformConnectionStateUpdates)
            {
                var platform =
                    await _platformManager.GetPlatformByExternalId(platformConnectionStateUpdate.PlatformId,
                                                                   session, cancellationToken);

                var platformConnection = user.PlatformConnections.SingleOrDefault(pc => pc.PlatformId == platform.Id);
                if (platformConnection == null)
                {
                    throw new PlatformConnectionDoesNotExistException(
                              "User does not have an existing connection to the platform");
                }

                if (platformConnectionStateUpdate.RemoveConnection)
                {
                    if (platformConnectionStateUpdate.ConnectedApps != null)
                    {
                        throw new ArgumentException("Cannot both remove connection and update connected apps");
                    }

                    // remove connection and all saved data
                    await _platformDataManager.RemovePlatformDataForPlatform(user.Id, platform.Id, session,
                                                                             cancellationToken);

                    var removedAppIds = user.PlatformConnections.Single(pc => pc.PlatformId == platform.Id)
                                        .ConnectionInfo.NotificationInfos.Select(ni => ni.AppId).ToList();
                    user.PlatformConnections.Remove(platformConnection);
                    await _appNotificationManager.NotifyPlatformConnectionRemoved(user.Id, removedAppIds, platform.Id,
                                                                                  session, cancellationToken);
                }
                else
                {
                    var existingApps = new List <App>();

                    foreach (var connectedApp in platformConnectionStateUpdate.ConnectedApps)
                    {
                        var correspondingApp =
                            await _appManager.GetAppFromApplicationId(connectedApp, session,
                                                                      cancellationToken);

                        if (existingApps.All(a => a.Id != correspondingApp.Id))
                        {
                            existingApps.Add(correspondingApp);
                        }

                        if (platformConnection.ConnectionInfo.NotificationInfos.All(ni =>
                                                                                    ni.AppId != correspondingApp.Id))
                        {
                            throw new ArgumentException(
                                      $"An existing connection between platform {platform.Name} and app {correspondingApp.Name} does not exist");
                        }
                    }

                    var updatedNotificationInfos = new List <NotificationInfo>();

                    var removedAppIds = new List <string>();

                    // update connected apps
                    foreach (var notificationInfo in platformConnection.ConnectionInfo.NotificationInfos)
                    {
                        var correspondingApp = existingApps.SingleOrDefault(a => a.Id == notificationInfo.AppId);
                        if (correspondingApp == null)
                        {
                            correspondingApp =
                                await _appManager.GetAppFromId(notificationInfo.AppId, session, cancellationToken);

                            existingApps.Add(correspondingApp);
                        }

                        if (platformConnectionStateUpdate.ConnectedApps.Any(applicationId =>
                                                                            applicationId == correspondingApp.ExternalId))
                        {
                            updatedNotificationInfos.Add(notificationInfo);
                        }
                        else
                        {
                            removedAppIds.Add(correspondingApp.Id);
                        }
                    }

                    platformConnection.ConnectionInfo.NotificationInfos = updatedNotificationInfos;

                    if (removedAppIds.Count > 0)
                    {
                        await _appNotificationManager.NotifyPlatformConnectionRemoved(user.Id, removedAppIds,
                                                                                      platform.Id, session, cancellationToken);
                    }
                }

                await session.SaveChangesAsync(cancellationToken);
            }

            // gather and return new state
            var platformIds = user.PlatformConnections.Select(pc => pc.PlatformId).ToList();
            var platforms   =
                (await _platformManager.GetPlatforms(platformIds, session, cancellationToken)).Values.ToList();
            var appIds = user.PlatformConnections.Select(pc => pc.ConnectionInfo)
                         .SelectMany(ci => ci.NotificationInfos).Select(ni => ni.AppId).Distinct().ToList();
            var apps = (await _appManager.GetAppsFromIds(appIds, session, cancellationToken)).ToList();

            return(new PlatformUserConnectionStateViewModel(user.PlatformConnections, platforms, apps));
        }