private void StartObservingRooms()
        {
            StopObserving();
            RealtimeService.ObserveAllChatRooms(room =>
            {
                if (string.IsNullOrEmpty(room.Id) || string.IsNullOrEmpty(room.Name))
                {
                    return;
                }

                ChatRoomItemViewModel existingRoom = Rooms.FirstOrDefault(r => r.Id == room.Id);
                if (existingRoom == null)
                {
                    Rooms.Add(new ChatRoomItemViewModel()
                    {
                        Name             = room.Name,
                        Id               = room.Id,
                        ParticipantCount = room.Users == null ? 0 : room.Users.Count
                    });
                }
                else
                {
                    existingRoom.Name             = room.Name;
                    existingRoom.ParticipantCount = room.Users == null ? 0 : room.Users.Count;
                }

                IsBusy = false;
            });
        }
예제 #2
0
        /// <summary> Check that a share link is valid for a project and add the user to the project. </summary>
        public async Task CheckLinkSharingAsync(string curUserId, string projectId, string shareKey)
        {
            using (IConnection conn = await RealtimeService.ConnectAsync(curUserId))
            {
                IDocument <SFProject> projectDoc = await GetProjectDocAsync(projectId, conn);

                if (projectDoc.Data.UserRoles.ContainsKey(curUserId))
                {
                    return;
                }

                IDocument <User> userDoc = await conn.FetchAsync <User>(curUserId);

                string projectRole;
                // Attempt to get the role for the user from the Paratext registry
                Attempt <string> attempt = await TryGetProjectRoleAsync(projectDoc.Data, curUserId);

                if (!attempt.TryResult(out projectRole))
                {
                    // Get the project role that is specified in the sharekey
                    Attempt <SFProjectSecret> psAttempt = await ProjectSecrets.TryGetAsync(projectId);

                    if (psAttempt.TryResult(out SFProjectSecret ps))
                    {
                        projectRole = ps.ShareKeys.SingleOrDefault(sk => sk.Key == shareKey)?.ProjectRole;
                    }
                }
                // The share key was invalid
                if (projectRole == null)
                {
                    throw new ForbiddenException();
                }

                bool linkSharing = projectDoc.Data.CheckingConfig.ShareEnabled &&
                                   projectDoc.Data.CheckingConfig.ShareLevel == CheckingShareLevel.Anyone;
                if (linkSharing)
                {
                    // Add the user and remove the specific user share key if it exists. Link sharing keys
                    // have Email set to null and will not be removed.
                    await AddUserToProjectAsync(conn, projectDoc, userDoc, projectRole, true);

                    return;
                }
                // Look for a valid specific user share key.
                SFProjectSecret projectSecret = await ProjectSecrets.UpdateAsync(
                    p => p.Id == projectId && p.ShareKeys.Any(
                        sk => sk.Email != null && sk.Key == shareKey && sk.ExpirationTime > DateTime.UtcNow),
                    update => update.RemoveAll(p => p.ShareKeys, sk => sk.Key == shareKey)
                    );

                if (projectSecret != null)
                {
                    await AddUserToProjectAsync(conn, projectDoc, userDoc, projectRole, false);

                    return;
                }
                throw new ForbiddenException();
            }
        }
 public void AddData(string answerSyncUserId1, string answerSyncUserId2, string commentSyncUserId1,
                     string commentSyncUserId2, bool useAudioResponses = false)
 {
     RealtimeService.AddRepository("questions", OTType.Json0, new MemoryRepository <Question>(new[]
     {
         new Question
         {
             Id       = "project01:question01",
             DataId   = "question01",
             VerseRef = new VerseRefData(40, 1, 1),
             Text     = useAudioResponses ? "" : "Test question?",
             Answers  =
             {
                 new Answer
                 {
                     DataId      = "answer01",
                     OwnerRef    = "user02",
                     SyncUserRef = answerSyncUserId1,
                     DateCreated = new DateTime(2019, 1, 1, 8, 0, 0, DateTimeKind.Utc),
                     Text        = useAudioResponses ? "" : "Test answer 1.",
                     Comments    =
                     {
                         new Comment
                         {
                             DataId      = "comment01",
                             OwnerRef    = "user03",
                             SyncUserRef = commentSyncUserId1,
                             DateCreated = new DateTime(2019, 1, 1, 9, 0, 0, DateTimeKind.Utc),
                             Text        = "Test comment 1."
                         }
                     }
                 },
                 new Answer
                 {
                     DataId        = "answer02",
                     OwnerRef      = "user04",
                     SyncUserRef   = answerSyncUserId2,
                     DateCreated   = new DateTime(2019, 1, 2, 8, 0, 0, DateTimeKind.Utc),
                     Text          = "Test answer 2.",
                     VerseRef      = new VerseRefData(40, 1, "2-3"),
                     ScriptureText = "This is some scripture.",
                     Comments      =
                     {
                         new Comment
                         {
                             DataId      = "comment02",
                             OwnerRef    = "user02",
                             SyncUserRef = commentSyncUserId2,
                             DateCreated = new DateTime(2019, 1, 2, 9, 0, 0, DateTimeKind.Utc),
                             Text        = "Test comment 2."
                         }
                     }
                 }
             }
         }
     }));
 }
예제 #4
0
        public async Task DeleteProjectAsync(string curUserId, string projectId)
        {
            string ptProjectId;

            using (IConnection conn = await RealtimeService.ConnectAsync(curUserId))
            {
                IDocument <SFProject> projectDoc = await conn.FetchAsync <SFProject>(projectId);

                if (!projectDoc.IsLoaded)
                {
                    throw new DataNotFoundException("The project does not exist.");
                }
                if (!IsProjectAdmin(projectDoc.Data, curUserId))
                {
                    throw new ForbiddenException();
                }

                ptProjectId = projectDoc.Data.ParatextId;
                // delete the project first, so that users get notified about the deletion
                string[] projectUserIds = projectDoc.Data.UserRoles.Keys.ToArray();
                await projectDoc.DeleteAsync();

                async Task removeUser(string projectUserId)
                {
                    IDocument <User> userDoc = await conn.FetchAsync <User>(projectUserId);

                    await RemoveUserFromProjectAsync(conn, projectDoc, userDoc);
                }

                var tasks = new List <Task>();
                foreach (string projectUserId in projectUserIds)
                {
                    tasks.Add(removeUser(projectUserId));
                }
                await Task.WhenAll(tasks);
            }

            await ProjectSecrets.DeleteAsync(projectId);

            await RealtimeService.DeleteProjectAsync(projectId);

            await _engineService.RemoveProjectAsync(projectId);

            string projectDir = Path.Combine(SiteOptions.Value.SiteDir, "sync", ptProjectId);

            if (FileSystemService.DirectoryExists(projectDir))
            {
                FileSystemService.DeleteDirectory(projectDir);
            }
            string audioDir = GetAudioDir(projectId);

            if (FileSystemService.DirectoryExists(audioDir))
            {
                FileSystemService.DeleteDirectory(audioDir);
            }
        }
예제 #5
0
        protected async Task <TModel> GetProjectAsync(string projectId)
        {
            Attempt <TModel> projectAttempt = await RealtimeService.TryGetSnapshotAsync <TModel>(projectId);

            if (!projectAttempt.TryResult(out TModel project))
            {
                throw new DataNotFoundException("The project does not exist.");
            }
            return(project);
        }
예제 #6
0
        /// <summary> Determine if the specified project is an active source project. </summary>
        public bool IsSourceProject(string projectId)
        {
            IQueryable <SFProject> projectQuery = RealtimeService.QuerySnapshots <SFProject>();

            return(projectQuery.Any(p =>
                                    p.TranslateConfig.Source != null &&
                                    p.TranslateConfig.Source.ProjectRef == projectId &&
                                    p.TranslateConfig.TranslationSuggestionsEnabled
                                    ));
        }
예제 #7
0
        public async Task <IEnumerable <SFProject> > GetSFProjects(string[] sfProjectIds)
        {
            List <SFProject> projectsResults = new List <SFProject>();

            foreach (string id in sfProjectIds)
            {
                SFProject proj = await RealtimeService.GetSnapshotAsync <SFProject>(id);

                projectsResults.Add(proj);
            }
            return(projectsResults);
        }
예제 #8
0
        public async Task SetSyncDisabledAsync(string curUserId, string systemRole, string projectId, bool isDisabled)
        {
            if (systemRole != SystemRole.SystemAdmin)
            {
                throw new ForbiddenException();
            }

            using (IConnection conn = await RealtimeService.ConnectAsync(curUserId))
            {
                IDocument <TModel> projectDoc = await GetProjectDocAsync(projectId, conn);

                await projectDoc.SubmitJson0OpAsync(op => op.Set(p => p.SyncDisabled, isDisabled));
            }
        }
예제 #9
0
        public async Task SyncAsync(string curUserId, string projectId)
        {
            Attempt <SFProject> attempt = await RealtimeService.TryGetSnapshotAsync <SFProject>(projectId);

            if (!attempt.TryResult(out SFProject project))
            {
                throw new DataNotFoundException("The project does not exist.");
            }

            if (!IsProjectAdmin(project, curUserId))
            {
                throw new ForbiddenException();
            }

            await _syncService.SyncAsync(curUserId, projectId, false);
        }
예제 #10
0
        public async Task <bool> InviteAsync(string curUserId, string projectId, string email)
        {
            SFProject project = await GetProjectAsync(projectId);

            if (await RealtimeService.QuerySnapshots <User>()
                .AnyAsync(u => project.UserRoles.Keys.Contains(u.Id) && u.Email == email))
            {
                return(false);
            }
            SiteOptions siteOptions = SiteOptions.Value;

            if (!project.CheckingConfig.ShareEnabled && !IsProjectAdmin(project, curUserId))
            {
                throw new ForbiddenException();
            }

            // Invite a specific person. Reuse prior code, if any.
            SFProjectSecret projectSecret = await ProjectSecrets.UpdateAsync(
                p => p.Id == projectId && !p.ShareKeys.Any(sk => sk.Email == email),
                update => update.Add(p => p.ShareKeys,
                                     new ShareKey {
                Email = email, Key = _securityService.GenerateKey()
            }));

            if (projectSecret == null)
            {
                projectSecret = await ProjectSecrets.GetAsync(projectId);
            }
            string key = projectSecret.ShareKeys.Single(sk => sk.Email == email).Key;
            string url = $"{siteOptions.Origin}projects/{projectId}?sharing=true&shareKey={key}";
            string emailSpecificLinkMessage = _localizer[SharedResource.Keys.InviteLinkSharingOff];

            User inviter = await RealtimeService.GetSnapshotAsync <User>(curUserId);

            string subject      = _localizer[SharedResource.Keys.InviteSubject, project.Name, siteOptions.Name];
            var    greeting     = $"<p>{_localizer[SharedResource.Keys.InviteGreeting, "<p>", inviter.Name, project.Name, siteOptions.Name, $"<a href=\"{url}\">{url}</a><p>"]}";
            var    instructions = $"<p>{_localizer[SharedResource.Keys.InviteInstructions, siteOptions.Name, "<b>", "</b>"]}";
            var    pt           = $"<ul><li>{_localizer[SharedResource.Keys.InvitePTOption, "<b>", "</b>", siteOptions.Name]}</li>";
            var    google       = $"<li>{_localizer[SharedResource.Keys.InviteGoogleOption, "<b>", "</b>", siteOptions.Name]}</li>";
            var    facebook     = $"<li>{_localizer[SharedResource.Keys.InviteFacebookOption, "<b>", "</b>", siteOptions.Name]}</li>";
            var    withemail    = $"<li>{_localizer[SharedResource.Keys.InviteEmailOption, siteOptions.Name]}</li></ul></p><p></p>";
            var    signoff      = $"<p>{_localizer[SharedResource.Keys.InviteSignature, "<p>", siteOptions.Name]}</p>";
            var    emailBody    = $"{greeting}{emailSpecificLinkMessage}{instructions}{pt}{google}{facebook}{withemail}{signoff}";
            await _emailService.SendEmailAsync(email, subject, emailBody);

            return(true);
        }
예제 #11
0
        /// <summary>
        /// Disassociate user projectUserId from project projectId, if curUserId is allowed to cause that.
        /// </summary>
        public async Task RemoveUserAsync(string curUserId, string projectId, string projectUserId)
        {
            if (curUserId == null || projectId == null || projectUserId == null)
            {
                throw new ArgumentNullException();
            }
            using (IConnection conn = await RealtimeService.ConnectAsync(curUserId))
            {
                IDocument <TModel> projectDoc = await GetProjectDocAsync(projectId, conn);

                if (curUserId != projectUserId && !IsProjectAdmin(projectDoc.Data, curUserId))
                {
                    throw new ForbiddenException();
                }
                await RemoveUserCoreAsync(conn, curUserId, projectId, projectUserId);
            }
        }
예제 #12
0
        public async Task <bool> HasTransceleratorQuestions(string curUserId, string projectId)
        {
            using (IConnection conn = await RealtimeService.ConnectAsync(curUserId))
            {
                IDocument <SFProject> projectDoc = await conn.FetchAsync <SFProject>(projectId);

                if (!projectDoc.IsLoaded)
                {
                    throw new DataNotFoundException("The project does not exist.");
                }
                if (!IsProjectAdmin(projectDoc.Data, curUserId))
                {
                    throw new ForbiddenException();
                }
                return(_transceleratorService.HasQuestions(projectDoc.Data.ParatextId));
            }
        }
예제 #13
0
        public async Task AddTranslateMetricsAsync(string curUserId, string projectId, TranslateMetrics metrics)
        {
            Attempt <SFProject> attempt = await RealtimeService.TryGetSnapshotAsync <SFProject>(projectId);

            if (!attempt.TryResult(out SFProject project))
            {
                throw new DataNotFoundException("The project does not exist.");
            }

            if (!project.UserRoles.ContainsKey(curUserId))
            {
                throw new ForbiddenException();
            }

            metrics.UserRef    = curUserId;
            metrics.ProjectRef = projectId;
            metrics.Timestamp  = DateTime.UtcNow;
            await _translateMetrics.ReplaceAsync(metrics, true);
        }
예제 #14
0
        public async Task CheckLinkSharingAsync(string curUserId, string projectId, string shareKey = null)
        {
            using (IConnection conn = await RealtimeService.ConnectAsync(curUserId))
            {
                IDocument <SFProject> projectDoc = await GetProjectDocAsync(projectId, conn);

                if (projectDoc.Data.UserRoles.ContainsKey(curUserId))
                {
                    return;
                }

                IDocument <User> userDoc = await conn.FetchAsync <User>(curUserId);

                Attempt <string> attempt = await TryGetProjectRoleAsync(projectDoc.Data, curUserId);

                string projectRole = attempt.Result;
                if (shareKey != null)
                {
                    string          currentUserEmail = userDoc.Data.Email;
                    SFProjectSecret projectSecret    = await ProjectSecrets.UpdateAsync(
                        p => p.Id == projectId &&
                        p.ShareKeys.Any(sk => sk.Email == currentUserEmail && sk.Key == shareKey),
                        update => update.RemoveAll(p => p.ShareKeys, sk => sk.Email == currentUserEmail));

                    if (projectSecret != null)
                    {
                        await AddUserToProjectAsync(conn, projectDoc, userDoc, projectRole, false);

                        return;
                    }
                }
                if (projectDoc.Data.CheckingConfig.ShareEnabled == true &&
                    projectDoc.Data.CheckingConfig.ShareLevel == CheckingShareLevel.Anyone)
                {
                    // Users with the project link get added to the project. This also covers the case where
                    // a user was emailed a share key and the invite was cancelled, but link sharing is enabled
                    await AddUserToProjectAsync(conn, projectDoc, userDoc, projectRole);

                    return;
                }
                throw new ForbiddenException();
            }
        }
예제 #15
0
        /// <summary>
        /// Disassociate user projectUserId from all projects on the site that this ProjectService is operating on.
        /// As requested by curUserId. Permissions to do so are not checked.
        /// </summary>
        public async Task RemoveUserFromAllProjectsAsync(string curUserId, string projectUserId)
        {
            if (curUserId == null || projectUserId == null)
            {
                throw new ArgumentNullException();
            }
            using (IConnection conn = await RealtimeService.ConnectAsync(curUserId))
            {
                IDocument <User> userDoc = await GetUserDocAsync(projectUserId, conn);

                IEnumerable <Task> removalTasks = userDoc.Data.Sites[SiteOptions.Value.Id].Projects.Select(
                    (string projectId) => RemoveUserCoreAsync(conn, curUserId, projectId, projectUserId));
                // The removals can be processed in parallel in production, but for unit tests, MemoryRealtimeService
                // does not fully implement concurrent editing of docs, so run them in a sequence.
                foreach (Task task in removalTasks)
                {
                    await task;
                }
            }
        }
예제 #16
0
        private void SendMessage()
        {
            ChatMessageViewModel newMessage = new ChatMessageViewModel()
            {
                Content  = _newMessage,
                IsBusy   = true,
                UserName = _userName
            };

            Messages.Add(newMessage);

            ChatMessage message = new ChatMessage()
            {
                Content  = _newMessage,
                UserName = _userName,
            };

            NewMessage = null;

            newMessage.Key = RealtimeService.SendMessage(message);
        }
예제 #17
0
        public async Task AddUserAsync(string curUserId, string projectId, string projectRole)
        {
            using (IConnection conn = await RealtimeService.ConnectAsync(curUserId))
            {
                IDocument <TModel> projectDoc = await GetProjectDocAsync(projectId, conn);

                IDocument <User> userDoc = await GetUserDocAsync(curUserId, conn);

                if (userDoc.Data.Role == SystemRole.User || projectRole == null)
                {
                    Attempt <string> attempt = await TryGetProjectRoleAsync(projectDoc.Data, curUserId);

                    if (!attempt.TryResult(out projectRole))
                    {
                        throw new ForbiddenException();
                    }
                }

                await AddUserToProjectAsync(conn, projectDoc, userDoc, projectRole);
            }
        }
예제 #18
0
 private void StartObservingMessages()
 {
     RealtimeService.ObserveMessages((message, key) =>
     {
         _dispatcher.RequestMainThreadAction(() =>
         {
             ChatMessageViewModel existingMessage = Messages.FirstOrDefault(m => m.Key == key);
             if (existingMessage == null)
             {
                 Debug.WriteLine(key);
                 Messages.Add(new ChatMessageViewModel()
                 {
                     Key      = key,
                     Content  = message.Content,
                     UserName = message.UserName
                 });
             }
             else
             {
                 existingMessage.IsBusy = false;
             }
         });
     });
 }
예제 #19
0
        /// <summary>
        /// Returns SF project id of created project.
        /// </summary>
        public async Task <string> CreateProjectAsync(string curUserId, SFProjectCreateSettings settings)
        {
            Attempt <UserSecret> userSecretAttempt = await _userSecrets.TryGetAsync(curUserId);

            if (!userSecretAttempt.TryResult(out UserSecret userSecret))
            {
                throw new DataNotFoundException("The user does not exist.");
            }

            IReadOnlyList <ParatextProject> ptProjects = await _paratextService.GetProjectsAsync(userSecret);

            ParatextProject ptProject = ptProjects.SingleOrDefault(p => p.ParatextId == settings.ParatextId);

            if (ptProject == null)
            {
                throw new DataNotFoundException("The paratext project does not exist.");
            }

            var project = new SFProject
            {
                ParatextId    = settings.ParatextId,
                Name          = ptProject.Name,
                ShortName     = ptProject.ShortName,
                WritingSystem = new WritingSystem {
                    Tag = ptProject.LanguageTag
                },
                TranslateConfig = new TranslateConfig
                {
                    TranslationSuggestionsEnabled = settings.TranslationSuggestionsEnabled
                },
                CheckingConfig = new CheckingConfig
                {
                    CheckingEnabled = settings.CheckingEnabled
                }
            };
            Attempt <string> attempt = await TryGetProjectRoleAsync(project, curUserId);

            if (!attempt.TryResult(out string projectRole) || projectRole != SFProjectRole.Administrator)
            {
                throw new ForbiddenException();
            }

            string projectId = ObjectId.GenerateNewId().ToString();

            using (IConnection conn = await RealtimeService.ConnectAsync(curUserId))
            {
                if (this.RealtimeService.QuerySnapshots <SFProject>().Any(
                        (SFProject sfProject) => sfProject.ParatextId == project.ParatextId))
                {
                    throw new InvalidOperationException(ErrorAlreadyConnectedKey);
                }
                IDocument <SFProject> projectDoc = await conn.CreateAsync <SFProject>(projectId, project);

                await ProjectSecrets.InsertAsync(new SFProjectSecret { Id = projectDoc.Id });

                IDocument <User> userDoc = await conn.FetchAsync <User>(curUserId);
                await AddUserToProjectAsync(conn, projectDoc, userDoc, SFProjectRole.Administrator, false);

                // Add the source after the project has been created
                // This will make the source project appear after the target, if it needs to be created
                if (settings.SourceParatextId != null && settings.SourceParatextId != settings.ParatextId)
                {
                    TranslateSource source = await this.GetTranslateSourceAsync(
                        curUserId, userSecret, settings.SourceParatextId, ptProjects);

                    await projectDoc.SubmitJson0OpAsync(op =>
                    {
                        UpdateSetting(op, p => p.TranslateConfig.Source, source);
                    });
                }

                if (projectDoc.Data.TranslateConfig.TranslationSuggestionsEnabled)
                {
                    var machineProject = new MachineProject
                    {
                        Id = projectDoc.Id,
                        SourceLanguageTag = projectDoc.Data.TranslateConfig.Source.WritingSystem.Tag,
                        TargetLanguageTag = projectDoc.Data.WritingSystem.Tag
                    };
                    await _engineService.AddProjectAsync(machineProject);
                }
            }

            await _syncService.SyncAsync(curUserId, projectId, true);

            return(projectId);
        }
예제 #20
0
 public EngagementHub()
 {
     _connectionService = new ConnectionService();
     _engagementService = new EngagementService();
     _realtimeService   = new RealtimeService();
 }
 public bool ContainsProject(string id)
 {
     return(RealtimeService.GetRepository <SFProject>().Contains(id));
 }
예제 #22
0
        public async Task <bool> InviteAsync(string curUserId, string projectId, string email, string locale,
                                             string role)
        {
            SFProject project = await GetProjectAsync(projectId);

            if (await RealtimeService.QuerySnapshots <User>()
                .AnyAsync(u => project.UserRoles.Keys.Contains(u.Id) && u.Email == email))
            {
                return(false);
            }
            SiteOptions siteOptions = SiteOptions.Value;

            if (!project.CheckingConfig.ShareEnabled && !IsProjectAdmin(project, curUserId))
            {
                throw new ForbiddenException();
            }
            CultureInfo.CurrentUICulture = new CultureInfo(locale);
            // Remove the user sharekey if expired
            await ProjectSecrets.UpdateAsync(
                p => p.Id == projectId,
                update => update.RemoveAll(p => p.ShareKeys,
                                           sk => sk.Email == email && sk.ExpirationTime < DateTime.UtcNow)
                );

            DateTime expTime = DateTime.UtcNow.AddDays(14);

            // Invite a specific person. Reuse prior code, if any.
            SFProjectSecret projectSecret = await ProjectSecrets.UpdateAsync(
                p => p.Id == projectId && !p.ShareKeys.Any(sk => sk.Email == email),
                update => update.Add(p => p.ShareKeys,
                                     new ShareKey
            {
                Email          = email,
                Key            = _securityService.GenerateKey(),
                ExpirationTime = expTime,
                ProjectRole    = role
            }
                                     )
                );

            if (projectSecret == null)
            {
                projectSecret = await ProjectSecrets.GetAsync(projectId);

                int index = projectSecret.ShareKeys.FindIndex(sk => sk.Email == email);

                // Renew the expiration time of the valid key
                await ProjectSecrets.UpdateAsync(
                    p => p.Id == projectId && p.ShareKeys.Any(sk => sk.Email == email),
                    update => update.Set(p => p.ShareKeys[index].ExpirationTime, expTime)
                    );
            }
            string key         = projectSecret.ShareKeys.Single(sk => sk.Email == email).Key;
            string url         = $"{siteOptions.Origin}projects/{projectId}?sharing=true&shareKey={key}&locale={locale}";
            string linkExpires = _localizer[SharedResource.Keys.InviteLinkExpires];

            User inviter = await RealtimeService.GetSnapshotAsync <User>(curUserId);

            string subject      = _localizer[SharedResource.Keys.InviteSubject, project.Name, siteOptions.Name];
            var    greeting     = $"<p>{_localizer[SharedResource.Keys.InviteGreeting, "<p>", inviter.Name, project.Name, siteOptions.Name, $"<a href=\"{url}\">{url}</a><p>"]}";
            var    instructions = $"<p>{_localizer[SharedResource.Keys.InviteInstructions, siteOptions.Name, "<b>", "</b>"]}";
            var    pt           = $"<ul><li>{_localizer[SharedResource.Keys.InvitePTOption, "<b>", "</b>", siteOptions.Name]}</li>";
            var    google       = $"<li>{_localizer[SharedResource.Keys.InviteGoogleOption, "<b>", "</b>", siteOptions.Name]}</li>";
            var    facebook     = $"<li>{_localizer[SharedResource.Keys.InviteFacebookOption, "<b>", "</b>", siteOptions.Name]}</li>";
            var    withemail    = $"<li>{_localizer[SharedResource.Keys.InviteEmailOption, siteOptions.Name]}</li></ul></p><p></p>";
            var    signoff      = $"<p>{_localizer[SharedResource.Keys.InviteSignature, "<p>", siteOptions.Name]}</p>";
            var    emailBody    = $"{greeting}{linkExpires}{instructions}{pt}{google}{facebook}{withemail}{signoff}";
            await _emailService.SendEmailAsync(email, subject, emailBody);

            return(true);
        }
예제 #23
0
        // The SetupSFData method was copied from ParatextSyncRunnerTests.cs, trimmed, and modified.
        public void SetupSFData(bool translationSuggestionsEnabled, bool checkingEnabled)
        {
            RealtimeService.AddRepository("users", OTType.Json0, new MemoryRepository <User>(new[]
            {
                new User
                {
                    Id         = "user01",
                    ParatextId = "pt01"
                },
                new User
                {
                    Id         = "user02",
                    ParatextId = "pt02"
                },
                new User
                {
                    Id         = "user03",
                    ParatextId = "pt03"
                }
            }));
            RealtimeService.AddRepository("sf_projects", OTType.Json0, new MemoryRepository <SFProject>(
                                              new[]
            {
                new SFProject
                {
                    Id        = "project01",
                    Name      = "project01",
                    ShortName = "P01",
                    UserRoles = new Dictionary <string, string>
                    {
                        { "user01", SFProjectRole.Administrator },
                        { "user02", SFProjectRole.Translator },
                        { "user03", SFProjectRole.Administrator }
                    },
                    ParatextId      = "target01",
                    TranslateConfig = new TranslateConfig
                    {
                        TranslationSuggestionsEnabled = translationSuggestionsEnabled,
                        Source = new TranslateSource
                        {
                            ParatextId    = "source01",
                            Name          = "Source",
                            ShortName     = "SRC",
                            WritingSystem = new WritingSystem
                            {
                                Tag = "en"
                            }
                        }
                    },
                    CheckingConfig = new CheckingConfig
                    {
                        CheckingEnabled = checkingEnabled
                    },
                    Sync = new Sync
                    {
                        QueuedCount = 1
                    }
                },
                new SFProject
                {
                    Id        = "project02",
                    Name      = "project02",
                    ShortName = "P02",
                    UserRoles = new Dictionary <string, string>
                    {
                        { "user01", SFProjectRole.Administrator },
                        { "user02", SFProjectRole.Translator },
                        { "user03", SFProjectRole.Administrator }
                    },
                    ParatextId      = "target02",
                    TranslateConfig = new TranslateConfig
                    {
                        TranslationSuggestionsEnabled = translationSuggestionsEnabled,
                        Source = new TranslateSource
                        {
                            ParatextId    = "source02",
                            Name          = "Source",
                            ShortName     = "SR2",
                            WritingSystem = new WritingSystem
                            {
                                Tag = "en"
                            }
                        }
                    },
                    CheckingConfig = new CheckingConfig
                    {
                        CheckingEnabled = checkingEnabled
                    },
                    Sync = new Sync
                    {
                        QueuedCount = 1
                    }
                }
            }));

            RealtimeService.AddRepository("texts", OTType.RichText, new MemoryRepository <TextData>());
            RealtimeService.AddRepository("questions", OTType.Json0, new MemoryRepository <Question>());
        }
 public RealtimeController()
 {
     service = new RealtimeService();
 }
예제 #25
0
 public TestProject GetProject(string id)
 {
     return(RealtimeService.GetRepository <TestProject>().Get(id));
 }
예제 #26
0
        public async Task UpdateSettingsAsync(string curUserId, string projectId, SFProjectSettings settings)
        {
            using (IConnection conn = await RealtimeService.ConnectAsync(curUserId))
            {
                IDocument <SFProject> projectDoc = await conn.FetchAsync <SFProject>(projectId);

                if (!projectDoc.IsLoaded)
                {
                    throw new DataNotFoundException("The project does not exist.");
                }
                if (!IsProjectAdmin(projectDoc.Data, curUserId))
                {
                    throw new ForbiddenException();
                }

                // Get the source - any creation or permission updates are handled in GetTranslateSourceAsync
                TranslateSource source = null;
                if (settings.SourceParatextId != null)
                {
                    Attempt <UserSecret> userSecretAttempt = await _userSecrets.TryGetAsync(curUserId);

                    if (!userSecretAttempt.TryResult(out UserSecret userSecret))
                    {
                        throw new DataNotFoundException("The user does not exist.");
                    }

                    IReadOnlyList <ParatextProject> ptProjects = await _paratextService.GetProjectsAsync(userSecret);

                    source = await GetTranslateSourceAsync(curUserId, userSecret, settings.SourceParatextId,
                                                           ptProjects, projectDoc.Data.UserRoles);

                    if (source.ProjectRef == projectId)
                    {
                        // A project cannot reference itself
                        source = null;
                    }
                }

                await projectDoc.SubmitJson0OpAsync(op =>
                {
                    UpdateSetting(op, p => p.TranslateConfig.TranslationSuggestionsEnabled,
                                  settings.TranslationSuggestionsEnabled);
                    UpdateSetting(op, p => p.TranslateConfig.Source, source);

                    UpdateSetting(op, p => p.CheckingConfig.CheckingEnabled, settings.CheckingEnabled);
                    UpdateSetting(op, p => p.CheckingConfig.UsersSeeEachOthersResponses,
                                  settings.UsersSeeEachOthersResponses);
                    UpdateSetting(op, p => p.CheckingConfig.ShareEnabled, settings.ShareEnabled);
                    UpdateSetting(op, p => p.CheckingConfig.ShareLevel, settings.ShareLevel);
                });

                bool suggestionsEnabledSet = settings.TranslationSuggestionsEnabled != null;
                bool sourceParatextIdSet   = settings.SourceParatextId != null;
                bool checkingEnabledSet    = settings.CheckingEnabled != null;
                // check if a sync needs to be run
                if (suggestionsEnabledSet || sourceParatextIdSet || checkingEnabledSet)
                {
                    bool trainEngine = false;
                    if (suggestionsEnabledSet || sourceParatextIdSet)
                    {
                        if (projectDoc.Data.TranslateConfig.TranslationSuggestionsEnabled &&
                            projectDoc.Data.TranslateConfig.Source != null)
                        {
                            // translate task was enabled or source project changed

                            // recreate Machine project only if source project changed
                            if (!suggestionsEnabledSet && sourceParatextIdSet)
                            {
                                await _engineService.RemoveProjectAsync(projectId);
                            }
                            var machineProject = new MachineProject
                            {
                                Id = projectId,
                                SourceLanguageTag = projectDoc.Data.TranslateConfig.Source.WritingSystem.Tag,
                                TargetLanguageTag = projectDoc.Data.WritingSystem.Tag
                            };
                            await _engineService.AddProjectAsync(machineProject);

                            trainEngine = true;
                        }
                        else
                        {
                            // translate task was disabled or source project set to null
                            await _engineService.RemoveProjectAsync(projectId);
                        }
                    }

                    await _syncService.SyncAsync(curUserId, projectId, trainEngine);
                }
            }
        }
예제 #27
0
 public AgentChatController()
 {
     _realtimeService = new RealtimeService();
 }
예제 #28
0
 public User GetUser(string id)
 {
     return(RealtimeService.GetRepository <User>().Get(id));
 }