Comment Sync impersonate + mentions sanitation

Originally asked by Maximillian Thomas Nadolny on 13 October 2021 (original question)


Hi dear Exalate Community,
I have a question regarding comments sync. We want to impersonate the author on the respective remote side and at the same time sanatize the mentions in the comment body. Stand alone both works using the following script snippets.

Impersonate comment author:
replica.addedComments.each

{ it.executor = nodeHelper.getUserByFullName(it.author.displayName) }

replica.changedComments.each

{ it.executor = nodeHelper.getUserByFullName(it.updateAuthor.displayName) }

issue.comments = commentHelper.mergeComments(issue, replica,

{it}

)

Sanatize Comment Mention:
def mentionFormat = replica.comments.collect {
comment ->

def matcher = comment.body =~ /{([^\}]*)}/
def newCommentBody = comment.body

matcher.each

{ target = nodeHelper.getUserByFullName(it[1])?.username ?: it[1] targetTarget = “[~$target]” newCommentBody = newCommentBody.replace(it[0],targetTarget) }

comment.body = newCommentBody
comment
}

As said this works great stand alone but when both are active depending on which comes first in the script only one function is applied.

We have tried the following in different variations but I don’t seem to be able to get it work:
issue.comments = commentHelper.mergeComments(issue, replica, {
if (it.author) it.executor = it.author
else it.executor = nodeHelper.getUserByEmail(it.author.displayName);
replica.comments.collect {
comment ->

def matcher = comment.body =~ /{([^\}]*)}/
def newCommentBody = comment.body

matcher.each

{ target = nodeHelper.getUserByFullName(it[1])?.username ?: it[1] targetTarget = “[~$target]” newCommentBody = newCommentBody.replace(it[0],targetTarget) }

comment.body = newCommentBody
comment

})

I know this would be a good addition to the community but I really need this to work by Friday and I am running out of time. It would be great if someone could help.

Cheers
Max


Answer by Andrii Markov on 26 October 2021

Hey Maximillian Thomas Nadolny ,

Could I ask you please to try this block instead of what you have:

replica.addedComments.each { it.executor = nodeHelper.getUserByFullName(it.author.displayName) }
replica.changedComments.each { it.executor = nodeHelper.getUserByFullName(it.updateAuthor.displayName) }
issue.comments = commentHelper.mergeComments(issue, replica, {
    comment ->
              

              def matcher  = comment.body =~ /\{([^\}]*)\}/
              def newCommentBody = comment.body

              matcher.each {
                  target = nodeHelper.getUserByFullName(it[1])?.username ?: it[1]
                  targetTarget = "[~$target]"
                  newCommentBody = newCommentBody.replace(it[0],targetTarget)
              }

              comment.body = newCommentBody
              comment
})

Kind Regards,
Andrii


Comments:

Maximillian Thomas Nadolny commented on 18 October 2021

Hi Andrii

thanks for the update. I’m afraid that won’t work for my use case or need. I may have to elaborate a little more.

As you are aware from previous tickets (EASE-10863) we have to separate and distinct Jira On-Prem Instances connected via VPN.

Both instances contain the same users but with different account IDs. As an example my account on one side is nado on the remote side is max.nadolny. But the Full Names are the same

For the impersonation of a user it works fine with the code snippet on both sides in the incoming sync. I suppose since I am receiving a User Object from which I can get the → Full Name which again can be found in either instance.

Which is this snippet → Incoming Sync

replica.addedComments.each

{ it.executor = nodeHelper.getUserByFullName(it.author.displayName) }

replica.changedComments.each

{ it.executor = nodeHelper.getUserByFullName(it.updateAuthor.displayName) }

issue.comments = commentHelper.mergeComments(issue, replica,

{it}

)

Now for the mention sanitation I had no such luck. What I want is:

-I explicitly want to receive notifications for the user on both instances

-Meaning a mention set on side A should produce a notification on system A get synced and produce a notification on system B and the other way round.

The problem is a mention looks something like this i.e. [~nado] and on the other side would have to look like this [~max.nadolny] and the same thing in the other direction.

To enable this I use this script snippet outgoing where I process al mentions and convert the account name into the full name:

replica.comments = issue.comments.collect {
comment ->

          def matcher  \= comment.body \=\~ /\\\[\~(\\w\+)\\]/ //different reg ex on each side → different account name formats  
          def newCommentBody \= comment.body  
         

          matcher.each {  
              target \= nodeHelper.getUser(it\[1])?.displayName ?: \[1]  
              targetTarget \= "{$target}"  
              newCommentBody \= newCommentBody.replace(it\[0], targetTarget)  
          }

          comment.body \= newCommentBody  
          comment  

}

on the receiving side I use this script snippet to format the body again and search for all Full Names and convert them back to the respective account name of the Jira Instance.

def mentionFormat = replica.comments.collect {
comment ->

          def matcher  \= comment.body \=\~ /\\{(\[^\\}]\*)\\}/  
          def newCommentBody \= comment.body

          matcher.each {  
              target \= nodeHelper.getUserByFullName(it\[1])?.username ?: it\[1]  
              targetTarget \= "\[\~$target]"  
              newCommentBody \= newCommentBody.replace(it\[0],targetTarget)  
          }

          comment.body \= newCommentBody  
          comment  

}

Now since you have suggested to make all the changes in the outgoing script I am absolutely sure it can’t work since system A has no idea of the users account names in system B and the other way round plus different as in the snippets I sent you are sanitizing the comments to something like this i.e. my account again as example in the comment body [~nado] bla bla bla becomes Max Nadolny bla bla bla which is not what I intended.

So what I really need is that these two work together →

replica.addedComments.each

{ it.executor = nodeHelper.getUserByFullName(it.author.displayName) }

replica.changedComments.each

{ it.executor = nodeHelper.getUserByFullName(it.updateAuthor.displayName) }

issue.comments = commentHelper.mergeComments(issue, replica,

{it}

)

___________________________________________________________________________________________________

def mentionFormat = replica.comments.collect {
comment ->

          def matcher  \= comment.body \=\~ /\\{(\[^\\}]\*)\\}/  
          def newCommentBody \= comment.body

          matcher.each {  
              target \= nodeHelper.getUserByFullName(it\[1])?.username ?: it\[1]  
              targetTarget \= "\[\~$target]"  
              newCommentBody \= newCommentBody.replace(it\[0],targetTarget)  
          }

          comment.body \= newCommentBody  
          comment  

}

______________________________________________________________________________________________________

As i have seen in some examples it should be able to get both to work within this function but I may be wrong:

issue.comments = commentHelper.mergeComments(issue, replica, {it})

Cheers and thank you ever so much for your effort and I am looking forward to your reply.

Cheers

Max

Answer by Maximillian Thomas Nadolny on 22 October 2021

Hello there,

Francis Martens (Exalate) I have seen some awesome script snippets by you and I know this probably is not super complicated or black magic but maybe you can help :smile:

You would be doing us an awesome favor we have been struggling for 2 weeks.

Cheers

Max


Answer by Andrii Markov on 18 October 2021

Hey Maximillian Thomas Nadolny ,

Could I ask you please to try it in this way?:

Outgoing sync:

def mentionX = { x ->
    def matcher  = x =~ /\[~accountid:([\w:-]+)\]/
    def newCommentbody = x
    matcher.each {

      target = nodeHelper.getUser(it[1])?.displayName ?: "Stranger"
        newCommentBody = newCommentBody.replace(it[0],target)

        }
    }

    newCommentBody
}

replica.addedComments = replica.addedComments.collect {c ->
    c.body = mentionX(c.body)
    c
}

Incoming sync:

issue.comments = commentHelper.mergeComments(issue, replica)