001/*
002 *  Copyright 2014 Anyware Services
003 *
004 *  Licensed under the Apache License, Version 2.0 (the "License");
005 *  you may not use this file except in compliance with the License.
006 *  You may obtain a copy of the License at
007 *
008 *      http://www.apache.org/licenses/LICENSE-2.0
009 *
010 *  Unless required by applicable law or agreed to in writing, software
011 *  distributed under the License is distributed on an "AS IS" BASIS,
012 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 *  See the License for the specific language governing permissions and
014 *  limitations under the License.
015 */
016
017package org.ametys.cms.repository.comment.ui;
018
019import java.io.IOException;
020import java.util.ArrayList;
021import java.util.HashMap;
022import java.util.List;
023import java.util.Map;
024
025import org.apache.avalon.framework.service.ServiceException;
026import org.apache.avalon.framework.service.ServiceManager;
027import org.apache.cocoon.ProcessingException;
028import org.apache.commons.lang.StringUtils;
029
030import org.ametys.cms.ObservationConstants;
031import org.ametys.cms.content.ContentHelper;
032import org.ametys.cms.repository.Content;
033import org.ametys.cms.repository.comment.Comment;
034import org.ametys.cms.repository.comment.CommentableContent;
035import org.ametys.core.observation.Event;
036import org.ametys.core.observation.ObservationManager;
037import org.ametys.core.right.RightManager.RightResult;
038import org.ametys.core.ui.Callable;
039import org.ametys.core.ui.StaticClientSideElement;
040import org.ametys.core.user.CurrentUserProvider;
041import org.ametys.core.user.UserIdentity;
042import org.ametys.plugins.repository.AmetysObjectResolver;
043import org.ametys.plugins.repository.UnknownAmetysObjectException;
044import org.ametys.plugins.repository.metadata.UnknownMetadataException;
045import org.ametys.runtime.parameter.ParameterHelper;
046
047/**
048 * This client site elements creates a button representing the validation state of a content's comment
049 */
050public class CommentClientSideElement extends StaticClientSideElement
051{
052    /** The constant for the name of the author from parameters */
053    public static final String PARAMETER_AUTHOR_NAME = "author-name";
054    /** The constant for the email of the author from parameters */
055    public static final String PARAMETER_AUTHOR_EMAIL = "author-email";
056    /** The constant for the hidden status of the email of the author from parameters */
057    public static final String PARAMETER_AUTHOR_EMAILHIDDEN = "author-emailhidden";
058    /** The constant for the url of the author from parameters */
059    public static final String PARAMETER_AUTHOR_URL = "author-url";
060    /** The constant for the text from parameters */
061    public static final String PARAMETER_TEXT = "text";
062    /** The constant for the content id from parameters */
063    public static final String PARAMETER_CONTENT_ID = "contentId";
064    /** The constant for the comment id from parameters */
065    public static final String PARAMETER_COMMENT_ID = "commentId";
066    /** The Ametys object resolver */
067    protected AmetysObjectResolver _resolver;
068    /** The current user provider */
069    protected CurrentUserProvider _userProvider;
070    /** The observation manager */
071    protected ObservationManager _observationManager;
072    /** The content helper */
073    private ContentHelper _contentHelper;
074
075    @Override
076    public void service(ServiceManager smanager) throws ServiceException
077    {
078        super.service(smanager);
079        _resolver = (AmetysObjectResolver) smanager.lookup(AmetysObjectResolver.ROLE);
080        _userProvider = (CurrentUserProvider) smanager.lookup(CurrentUserProvider.ROLE);
081        _observationManager = (ObservationManager) smanager.lookup(ObservationManager.ROLE);
082        _contentHelper = (ContentHelper) smanager.lookup(ContentHelper.ROLE);
083    }
084    
085    /**
086     * Return the list of comments with its validation state
087     * @param parameters The contents and their comments
088     * @return The comments and their validated status
089     */
090    @Callable
091    public Map<String, Object> getComments(Map<String, Object> parameters)
092    {
093        Map<String, Object> results = new HashMap<>();
094        results.put("comments", new ArrayList<Map<String, Object>>());
095        
096        for (String contentId : parameters.keySet())
097        {
098            try
099            {
100                Content content = _resolver.resolveById(contentId);
101                if (content instanceof CommentableContent)
102                {
103                    CommentableContent cContent = (CommentableContent) content;
104                    
105                    @SuppressWarnings("unchecked")
106                    List<String> commentIds = (List<String>) parameters.get(contentId);
107                    
108                    for (String commentId : commentIds)
109                    {
110                        try
111                        {
112                            Comment comment = cContent.getComment(commentId);
113                            @SuppressWarnings("unchecked")
114                            List<Map<String, Object>> comments = (List<Map<String, Object>>) results.get("comments");
115                            comments.add(getCommentParameters(cContent, comment));
116                        }
117                        catch (UnknownMetadataException e)
118                        {
119                            getLogger().warn("Ignoring request to get comment status " + contentId + " " + commentId + " because it does not exist", e);
120                        }
121                    }   
122                }
123                else
124                {
125                    getLogger().warn("Ignoring request to get comments status on non commentable content " + contentId);
126                }            
127            }
128            catch (UnknownAmetysObjectException e)
129            {
130                getLogger().warn("Ignoring request to get comments status on inexisting content " + contentId, e);
131            }
132        }
133        
134        return results;
135    }
136    
137    /**
138     * Get a comment properties
139     * @param contentId the id of the content
140     * @param commentId the id of the comment. Can be null
141     * @return results the server's response in JSON.
142     * @throws IOException If an error occured
143     * @throws ProcessingException If an error occured
144     */
145    @Callable
146    public Map<String, Object> getComment(String contentId, String commentId) throws IOException, ProcessingException
147    {
148        Map<String, Object> results = new HashMap<> ();
149               
150        UserIdentity user = _userProvider.getUser();
151        
152        Map<String, Object> comments = new HashMap<> ();
153        
154        Content content = _resolver.resolveById(contentId);
155
156        if (content instanceof CommentableContent)
157        {
158            if (_rightManager.hasRight(user, "CMS_Rights_CommentModerate", content) == RightResult.RIGHT_ALLOW)
159            {
160                CommentableContent commentableContent = (CommentableContent) content;
161                List<Comment> commentList = commentableContent.getComments(true, true);
162                
163                for (Comment comment : commentList)
164                {
165                    if (StringUtils.isNotEmpty(commentId) && !commentId.equals(comment.getId()))
166                    {
167                        continue;
168                    }
169                    
170                    comments = _jsonifyComment(comment, content);
171                }
172            }
173        }
174        
175        results.put("comments", comments);
176        return results;
177    }
178
179    /**
180     * Edit a comment if connected user has sufficient rights
181     * @param parameters the JS parameters. Necessarily contains the content and comment id, and the values to edit
182     * @return An empty map
183     */
184    @Callable 
185    public Map<String, Object> editComment(Map<String, Object> parameters)
186    {
187        String contentId = (String) parameters.get(PARAMETER_CONTENT_ID);
188        String commentId = (String) parameters.get(PARAMETER_COMMENT_ID);
189        
190        try
191        {
192            Content content = _resolver.resolveById(contentId);
193
194            if (!hasRight("CMS_Rights_CommentModerate", content))
195            {
196                String errorMessage = "User " + getCurrentUser() + " try to edit a comment on content of id '" + contentId + "' with no sufficient rights"; 
197                getLogger().error(errorMessage);
198                throw new IllegalStateException(errorMessage);
199            }
200            
201            if (!(content instanceof CommentableContent))
202            {
203                String errorMessage = "Can not edit comment for non-commentable content of id '" + contentId + "'"; 
204                getLogger().error(errorMessage);
205                throw new IllegalStateException(errorMessage);
206            }
207            
208            CommentableContent cContent = (CommentableContent) content;
209            
210            Comment comment = cContent.getComment(commentId);
211            
212            String oldAuthorName = comment.getAuthorName();
213            String oldAuthorEmail = comment.getAuthorEmail();
214            boolean oldAuthorEmailHidden = comment.isEmailHidden();
215            String oldAuthorURL = comment.getAuthorURL();
216            String oldContent = comment.getContent();
217            
218            boolean needSave = false;
219            
220            String authorName = (String) parameters.get(PARAMETER_AUTHOR_NAME);
221            if (!authorName.equals(oldAuthorName))
222            {
223                comment.setAuthorName(authorName);
224                needSave = true;
225            }
226            
227            String authorEmail = (String) parameters.get(PARAMETER_AUTHOR_EMAIL);
228            if (!authorEmail.equals(oldAuthorEmail))
229            {
230                comment.setAuthorEmail(authorEmail);
231                needSave = true;
232            }
233            
234            boolean authorEmailHidden = (Boolean) parameters.get(PARAMETER_AUTHOR_EMAILHIDDEN);
235            if (authorEmailHidden != oldAuthorEmailHidden)
236            {
237                comment.setEmailHiddenStatus(authorEmailHidden);
238                needSave = true;
239            }
240            
241            String authorUrl = (String) parameters.get(PARAMETER_AUTHOR_URL);
242            if (!authorUrl.equals(oldAuthorURL))
243            {
244                comment.setAuthorURL(authorUrl);
245                needSave = true;
246            }
247            
248            String text = (String) parameters.get(PARAMETER_TEXT);
249            if (!text.equals(oldContent))
250            {
251                comment.setContent(text);
252                needSave = true;
253            }
254            
255            if (needSave)
256            {
257                cContent.saveChanges();
258                
259                Map<String, Object> eventParams = new HashMap<>();
260                eventParams.put(ObservationConstants.ARGS_CONTENT, content);
261                eventParams.put(ObservationConstants.ARGS_COMMENT, comment);
262                eventParams.put("content.comment.old.author", oldAuthorName);
263                eventParams.put("content.comment.old.author.email", oldAuthorEmail);
264                eventParams.put("content.comment.old.author.email.hidden", oldAuthorEmailHidden);
265                eventParams.put("content.comment.old.author.url", oldAuthorURL);
266                eventParams.put("content.comment.old.content", oldContent);
267                
268                _observationManager.notify(new Event(ObservationConstants.EVENT_CONTENT_COMMENT_MODIFYING, getCurrentUser(), eventParams));
269            }
270        }
271        catch (UnknownAmetysObjectException e)
272        {
273            getLogger().error("Unknown content of id '" + contentId + "'", e);
274            throw new IllegalArgumentException("Unknown content of id '" + contentId + "'", e);
275        }
276        catch (UnknownMetadataException e)
277        {
278            getLogger().error("Unknown comment of id '" + commentId + "' for content '" + contentId + "'", e);
279            throw new IllegalArgumentException("Unknown comment of id '" + commentId + "' for content '" + contentId + "'", e);
280        }
281        
282        return java.util.Collections.EMPTY_MAP;
283    }
284    
285    /**
286     * Removes comments
287     * @param contents the contents with comments to remove
288     * @return the JSON result with deleted comments or not
289     */
290    @SuppressWarnings("unchecked")
291    @Callable
292    public Map<String, Object> deleteComments(Map<String, List<String>> contents)
293    {
294        Map<String, Object> results = new HashMap<> ();
295        
296        results.put("deleted-comments", new ArrayList<Map<String, Object>>());
297        results.put("undeleted-comments", new ArrayList<Map<String, Object>>());
298        results.put("uncommentable-contents", new ArrayList<Map<String, Object>>());
299        results.put("noright-contents", new ArrayList<Map<String, Object>>());
300        results.put("unknown-contents", new ArrayList<Map<String, Object>>());
301        
302        for (String contentId : contents.keySet())
303        {
304            try
305            {
306                Content content = _resolver.resolveById(contentId);
307                
308                if (hasRight("CMS_Rights_CommentModerate", content))
309                {
310                    // For each associated comment
311                    for (String commentId : contents.get(contentId))
312                    {
313                        Map<String, Object> commentParams = new HashMap<>();
314                        commentParams.put("id", commentId);
315                        commentParams.put("contentId", contentId);
316                        commentParams.put("contentTitle", _contentHelper.getTitle(content));
317                        
318                        if (content instanceof CommentableContent)
319                        {
320                            CommentableContent cContent = (CommentableContent) content;
321        
322                            try
323                            {
324                                Comment comment = cContent.getComment(commentId);
325                                
326                                Map<String, Object> eventParams = new HashMap<>();
327                                eventParams.put(ObservationConstants.ARGS_CONTENT, content);
328                                eventParams.put(ObservationConstants.ARGS_COMMENT_ID, comment.getId());
329                                eventParams.put(ObservationConstants.ARGS_COMMENT_AUTHOR, comment.getAuthorName());
330                                eventParams.put(ObservationConstants.ARGS_COMMENT_AUTHOR_EMAIL, comment.getAuthorEmail());
331                                eventParams.put(ObservationConstants.ARGS_COMMENT_VALIDATED, comment.isValidated());
332                                eventParams.put("comment.content", comment.getContent());
333                                
334                                _observationManager.notify(new Event(ObservationConstants.EVENT_CONTENT_COMMENT_DELETING, getCurrentUser(), eventParams));
335                                
336                                comment.remove();
337                                cContent.saveChanges();
338        
339                                List<Map<String, Object>> deletedComments = (List<Map<String, Object>>) results.get("deleted-comments");
340                                deletedComments.add(commentParams);
341                                
342                                _observationManager.notify(new Event(ObservationConstants.EVENT_CONTENT_COMMENT_DELETED, getCurrentUser(), eventParams));
343                            }
344                            catch (UnknownMetadataException e)
345                            {
346                                getLogger().error("Can not remove a non existing comment", e);
347                                
348                                List<Map<String, Object>> undeletedComments = (List<Map<String, Object>>) results.get("undeleted-comments");
349                                undeletedComments.add(commentParams);
350                            }
351                        }
352                        else
353                        {
354                            getLogger().error("Can not remove a comment on a non commentable content");
355                            
356                            List<Map<String, Object>> uncommentableContents = (List<Map<String, Object>>) results.get("uncommentable-contents");
357                            uncommentableContents.add(commentParams);
358                        }
359                    }
360                }
361                else
362                {
363                    // No right
364                    getLogger().error("User '" + getCurrentUser() + "' does not have right to moderate comments on content '" + content.getId() + "'");
365                    
366                    Map<String, Object> contentParams = new HashMap<>();
367                    contentParams.put("contentId", contentId);
368                    contentParams.put("contentTitle", _contentHelper.getTitle(content));
369                    
370                    List<Map<String, Object>> norightContents = (List<Map<String, Object>>) results.get("noright-contents");
371                    norightContents.add(contentParams);
372                }
373            }
374            catch (UnknownAmetysObjectException e)
375            {
376                getLogger().error("Can not remove a comment on a non existing content", e);
377                
378                Map<String, Object> contentParams = new HashMap<>();
379                contentParams.put("contentId", contentId);
380                
381                List<Map<String, Object>> unknownContents = (List<Map<String, Object>>) results.get("unknown-contents");
382                unknownContents.add(contentParams);
383            }
384        }
385
386        return results;
387    }
388    
389    /**
390     * Validates comments when it is possible.
391     * @param contents the contents with comments to validate
392     * @return the JSON result with validated comments or not
393     */
394    @SuppressWarnings("unchecked")
395    @Callable
396    public Map<String, Object> validateComments(Map<String, List<String>> contents)
397    {
398        Map<String, Object> results = new HashMap<>();
399
400        results.put("validated-comments", new ArrayList<Map<String, Object>>());
401        results.put("error-comments", new ArrayList<Map<String, Object>>());
402        results.put("uncommentable-contents", new ArrayList<Map<String, Object>>());
403        results.put("noright-contents", new ArrayList<Map<String, Object>>());
404        results.put("unknown-contents", new ArrayList<Map<String, Object>>());
405        
406        for (String contentId : contents.keySet())
407        {
408            try
409            {
410                Content content = _resolver.resolveById(contentId);
411                
412                if (hasRight("CMS_Rights_CommentModerate", content))
413                {
414                    // For each associated comment
415                    for (String commentId : contents.get(contentId))
416                    {
417                        Map<String, Object> commentParams = new HashMap<>();
418                        commentParams.put("id", commentId);
419                        commentParams.put("contentId", contentId);
420                        commentParams.put("contentTitle", _contentHelper.getTitle(content));
421                        
422                        if (content instanceof CommentableContent)
423                        {
424                            CommentableContent cContent = (CommentableContent) content;
425        
426                            try
427                            {
428                                Comment comment = cContent.getComment(commentId);
429                                if (!comment.isValidated())
430                                {
431                                    comment.setValidated(true);
432                                    cContent.saveChanges();
433                                    
434                                    List<Map<String, Object>> validatedComments = (List<Map<String, Object>>) results.get("validated-comments");
435                                    validatedComments.add(commentParams);
436                                    
437                                    Map<String, Object> eventParams = new HashMap<>();
438                                    eventParams.put(ObservationConstants.ARGS_CONTENT, content);
439                                    eventParams.put(ObservationConstants.ARGS_COMMENT, comment);
440                                    _observationManager.notify(new Event(ObservationConstants.EVENT_CONTENT_COMMENT_VALIDATED, getCurrentUser(), eventParams));
441                                }
442                            }
443                            catch (UnknownMetadataException e)
444                            {
445                                getLogger().error("Can not validate a non existing comment", e);
446                                
447                                List<Map<String, Object>> errorComments = (List<Map<String, Object>>) results.get("error-comments");
448                                errorComments.add(commentParams);
449                            }
450                        }
451                        else
452                        {
453                            getLogger().error("Can not validate a comment on a non commentable content");
454                            
455                            List<Map<String, Object>> errorComments = (List<Map<String, Object>>) results.get("error-comments");
456                            errorComments.add(commentParams);
457                        }
458                    }
459                }
460                else
461                {
462                    // No right
463                    getLogger().error("User '" + getCurrentUser() + "' does not have right to validate comments on content '" + content.getId() + "'");
464                    
465                    Map<String, Object> contentParams = new HashMap<>();
466                    contentParams.put("contentId", contentId);
467                    contentParams.put("contentTitle", _contentHelper.getTitle(content));
468                }
469            }
470            catch (UnknownAmetysObjectException e)
471            {
472                getLogger().error("Can not validate a comment on a non existing content", e);
473                
474                Map<String, Object> contentParams = new HashMap<>();
475                contentParams.put("contentId", contentId);
476                
477                List<Map<String, Object>> unknownContents = (List<Map<String, Object>>) results.get("unknown-contents");
478                unknownContents.add(contentParams);
479            }
480        }
481
482        return results;
483    }
484    
485    /**
486     * Invalidates comments when it is possible.
487     * @param contents the contents with comments to invalidate
488     * @return the JSON result with invalidated comments or not
489     */
490    @SuppressWarnings("unchecked")
491    @Callable
492    public Map<String, Object> invalidateComments(Map<String, List<String>> contents)
493    {
494        Map<String, Object> results = new HashMap<>();
495
496        results.put("unvalidated-comments", new ArrayList<Map<String, Object>>());
497        results.put("error-comments", new ArrayList<Map<String, Object>>());
498        results.put("uncommentable-contents", new ArrayList<Map<String, Object>>());
499        results.put("noright-contents", new ArrayList<Map<String, Object>>());
500        results.put("unknown-contents", new ArrayList<Map<String, Object>>());
501        
502        for (String contentId : contents.keySet())
503        {
504            try
505            {
506                Content content = _resolver.resolveById(contentId);
507                
508                if (hasRight("CMS_Rights_CommentModerate", content))
509                {
510                    // For each associated comment
511                    for (String commentId : contents.get(contentId))
512                    {
513                        Map<String, Object> commentParams = new HashMap<>();
514                        commentParams.put("id", commentId);
515                        commentParams.put("contentId", contentId);
516                        commentParams.put("contentTitle", _contentHelper.getTitle(content));
517                        
518                        if (content instanceof CommentableContent)
519                        {
520                            CommentableContent cContent = (CommentableContent) content;
521        
522                            try
523                            {
524                                Comment comment = cContent.getComment(commentId);
525                                if (comment.isValidated())
526                                {
527                                    comment.setValidated(false);
528                                    cContent.saveChanges();
529                                    
530                                    List<Map<String, Object>> validatedComments = (List<Map<String, Object>>) results.get("unvalidated-comments");
531                                    validatedComments.add(commentParams);
532                                    
533                                    Map<String, Object> eventParams = new HashMap<>();
534                                    eventParams.put(ObservationConstants.ARGS_CONTENT, content);
535                                    eventParams.put(ObservationConstants.ARGS_COMMENT, comment);
536                                    _observationManager.notify(new Event(ObservationConstants.EVENT_CONTENT_COMMENT_UNVALIDATED, getCurrentUser(), eventParams));
537                                }
538                            }
539                            catch (UnknownMetadataException e)
540                            {
541                                getLogger().error("Can not validate a non existing comment", e);
542                                
543                                List<Map<String, Object>> errorComments = (List<Map<String, Object>>) results.get("error-comments");
544                                errorComments.add(commentParams);
545                            }
546                        }
547                        else
548                        {
549                            getLogger().error("Can not validate a comment on a non commentable content");
550                            
551                            List<Map<String, Object>> errorComments = (List<Map<String, Object>>) results.get("error-comments");
552                            errorComments.add(commentParams);
553                        }
554                    }
555                }
556                else
557                {
558                    // No right
559                    getLogger().error("User '" + getCurrentUser() + "' does not have right to validate comments on content '" + content.getId() + "'");
560                    
561                    Map<String, Object> contentParams = new HashMap<>();
562                    contentParams.put("contentId", contentId);
563                    contentParams.put("contentTitle", _contentHelper.getTitle(content));
564                }
565            }
566            catch (UnknownAmetysObjectException e)
567            {
568                getLogger().error("Can not validate a comment on a non existing content", e);
569                
570                Map<String, Object> contentParams = new HashMap<>();
571                contentParams.put("contentId", contentId);
572                
573                List<Map<String, Object>> unknownContents = (List<Map<String, Object>>) results.get("unknown-contents");
574                unknownContents.add(contentParams);
575            }
576        }
577
578        return results;
579    }
580    
581    /**
582     * Jsonify the comment.
583     * @param comment The comment
584     * @param content The content
585     * @return commentMap the comment map
586     */
587    protected Map<String, Object> _jsonifyComment (Comment comment, Content content) 
588    {
589        Map<String, Object> result = new HashMap<> ();
590        
591        Map<String, Object> commentMap = new HashMap<> ();
592            
593        
594        commentMap.put("validated", Boolean.toString(comment.isValidated()));
595        commentMap.put("id", comment.getId());
596        commentMap.put("creationDate", ParameterHelper.valueToString(comment.getCreationDate()));
597        
598        String authorName = comment.getAuthorName();
599        if (authorName != null)
600        {
601            commentMap.put("author-name", authorName);
602        }
603        
604        String authorEmail = comment.getAuthorEmail();
605        if (authorEmail != null)
606        {
607            Map<String, Object> authorEmailMap = new HashMap<> ();
608            authorEmailMap.put("hidden", Boolean.toString(comment.isEmailHidden()));
609            authorEmailMap.put("value", authorEmail);
610            commentMap.put("author-email", authorEmailMap);
611        }
612        
613        String authorUrl = comment.getAuthorURL();
614        if (authorUrl != null)
615        {
616            commentMap.put("author-url", authorUrl);
617        }
618        
619        String text = comment.getContent();
620        if (text != null)
621        {
622            commentMap.put("text", comment.getContent());
623        }
624        commentMap.put("content", _jsonifyContent(content));
625        
626        result.put("comment", commentMap);
627        
628        return result;
629    }
630    
631    /**
632     * Jsonify the content.
633     * @param content The content
634     * @return contentMap the content map
635     */
636    protected Map<String, Object> _jsonifyContent (Content content) 
637    {
638        Map<String, Object> contentMap = new HashMap<> ();
639        
640        contentMap.put("id", content.getId());
641        contentMap.put("title", _contentHelper.getTitle(content));
642        contentMap.put("name", content.getName());
643        
644        return contentMap;
645    }
646
647    /**
648     * Get the parameters for a comment
649     * @param content The content
650     * @param comment The comment
651     * @return The parameters
652     */
653    protected Map<String, Object> getCommentParameters (Content content, Comment comment)
654    {
655        Map<String, Object> params = new HashMap<>();
656        
657        params.put("contentId", content.getId());
658        params.put("contentTitle", _contentHelper.getTitle(content));
659        params.put("id", comment.getId());
660        params.put("validated", comment.isValidated());
661        
662        return params;
663    }
664    
665    /**
666     * Get the current user
667     * @return The current user
668     */
669    protected UserIdentity getCurrentUser ()
670    {
671        return _userProvider.getUser();
672    }
673
674    /**
675     * Determines if connected user has right on content
676     * @param rightId The right id
677     * @param content The content
678     * @return true if user has right
679     */
680    protected boolean hasRight (String rightId, Content content)
681    {
682        UserIdentity user = _userProvider.getUser();
683        
684        return _rightManager.hasRight(user, "CMS_Rights_CommentModerate", content) == RightResult.RIGHT_ALLOW;
685    }
686}