Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
S
scratch-www
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Analytics
Analytics
Repository
Value Stream
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Commits
Open sidebar
xpstem
scratch-www
Commits
e331c20d
Unverified
Commit
e331c20d
authored
Jun 23, 2021
by
Paul Kaplan
Committed by
GitHub
Jun 23, 2021
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #5649 from paulkaplan/no-report-own-comments
Fix permissions issues on studio comments
parents
5b17870c
810465bf
Changes
6
Show whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
53 additions
and
37 deletions
+53
-37
src/redux/studio-permissions.js
src/redux/studio-permissions.js
+8
-5
src/views/preview/comment/top-level-comment.jsx
src/views/preview/comment/top-level-comment.jsx
+5
-3
src/views/studio/studio-comment.js
src/views/studio/studio-comment.js
+17
-0
src/views/studio/studio-comments.jsx
src/views/studio/studio-comments.jsx
+3
-20
test/unit/components/studio-comments.test.jsx
test/unit/components/studio-comments.test.jsx
+6
-0
test/unit/redux/studio-permissions.test.js
test/unit/redux/studio-permissions.test.js
+14
-9
No files found.
src/redux/studio-permissions.js
View file @
e331c20d
...
...
@@ -18,14 +18,18 @@ const selectCanAddProjects = state =>
// This isn't "canComment" since they could be muted, but comment composer handles that
const
selectShowCommentComposer
=
state
=>
selectIsSocial
(
state
);
const
selectCanReportComment
=
state
=>
selectIsSocial
(
state
);
const
selectCanReportComment
=
(
state
,
commentUsername
)
=>
selectIsLoggedIn
(
state
)
&&
selectUsername
(
state
)
!==
commentUsername
;
const
selectCanRestoreComment
=
state
=>
selectIsAdmin
(
state
);
// On the project page, project owners can delete comments with a confirmation,
// and admins can delete comments without a confirmation.
// On the studio page, studio creators and managers have the ability to delete *their own* comments with confirmation.
// Admins can delete comments without a confirmation.
const
selectCanDeleteAnyComment
=
state
=>
selectIsAdmin
(
state
);
const
selectCanDeleteOwnComment
=
state
=>
isCreator
(
state
)
||
isManager
(
state
);
const
selectCanDeleteComment
=
(
state
,
commentUsername
)
=>
{
if
(
selectIsAdmin
(
state
))
return
true
;
if
(
isManager
(
state
)
&&
selectUsername
(
state
)
===
commentUsername
)
return
true
;
return
false
;
};
const
selectCanDeleteCommentWithoutConfirm
=
state
=>
selectIsAdmin
(
state
);
const
selectCanFollowStudio
=
state
=>
selectIsLoggedIn
(
state
);
...
...
@@ -82,8 +86,7 @@ export {
selectCanAddProjects
,
selectCanFollowStudio
,
selectShowCommentComposer
,
selectCanDeleteAnyComment
,
selectCanDeleteOwnComment
,
selectCanDeleteComment
,
selectCanDeleteCommentWithoutConfirm
,
selectCanReportComment
,
selectCanRestoreComment
,
...
...
src/views/preview/comment/top-level-comment.jsx
View file @
e331c20d
...
...
@@ -131,7 +131,7 @@ class TopLevelComment extends React.Component {
return
(
<
FlexRow
className=
"comment-container"
>
<
Comm
ent
<
this
.
props
.
commentCompon
ent
highlighted=
{
highlightedCommentId
===
id
}
postURI=
{
postURI
}
onAddComment=
{
this
.
handleAddComment
}
...
...
@@ -173,7 +173,7 @@ class TopLevelComment extends React.Component {
<
React
.
Fragment
key=
{
`reply-and-status-${reply.id}`
}
>
<
Comm
ent
<
this
.
props
.
commentCompon
ent
author=
{
reply
.
author
}
canDelete=
{
canDelete
}
canDeleteWithoutConfirm=
{
canDeleteWithoutConfirm
}
...
...
@@ -233,6 +233,7 @@ TopLevelComment.propTypes = {
canReply
:
PropTypes
.
bool
,
canReport
:
PropTypes
.
bool
,
canRestore
:
PropTypes
.
bool
,
commentComponent
:
PropTypes
.
func
,
content
:
PropTypes
.
string
,
datetimeCreated
:
PropTypes
.
string
,
defaultExpanded
:
PropTypes
.
bool
,
...
...
@@ -260,7 +261,8 @@ TopLevelComment.defaultProps = {
defaultExpanded
:
false
,
hasThreadLimit
:
false
,
moreRepliesToLoad
:
false
,
threadHasReplyStatus
:
false
threadHasReplyStatus
:
false
,
commentComponent
:
Comment
};
module
.
exports
=
TopLevelComment
;
src/views/studio/studio-comment.js
0 → 100644
View file @
e331c20d
import
{
connect
}
from
'
react-redux
'
;
import
Comment
from
'
../preview/comment/comment.jsx
'
;
import
{
selectCanDeleteComment
,
selectCanReportComment
,
selectShowCommentComposer
}
from
'
../../redux/studio-permissions
'
;
import
{
selectStudioCommentsAllowed
}
from
'
../../redux/studio.js
'
;
export
default
connect
(
(
state
,
ownProps
)
=>
({
canReport
:
selectCanReportComment
(
state
,
ownProps
.
author
.
username
),
canDelete
:
selectCanDeleteComment
(
state
,
ownProps
.
author
.
username
),
canReply
:
selectShowCommentComposer
(
state
)
&&
selectStudioCommentsAllowed
(
state
)
})
)(
Comment
);
src/views/studio/studio-comments.jsx
View file @
e331c20d
...
...
@@ -10,19 +10,17 @@ import TopLevelComment from '../preview/comment/top-level-comment.jsx';
import
studioCommentActions
from
'
../../redux/studio-comment-actions.js
'
;
import
StudioCommentsAllowed
from
'
./studio-comments-allowed.jsx
'
;
import
StudioCommentsNotAllowed
from
'
./studio-comments-not-allowed.jsx
'
;
import
{
selectIsAdmin
,
selectHasFetchedSession
,
selectUsername
}
from
'
../../redux/session
'
;
import
{
selectIsAdmin
,
selectHasFetchedSession
}
from
'
../../redux/session
'
;
import
{
selectShowCommentComposer
,
selectCanDeleteAnyComment
,
selectCanDeleteOwnComment
,
selectCanDeleteCommentWithoutConfirm
,
selectCanReportComment
,
selectCanRestoreComment
,
selectCanEditCommentsAllowed
,
selectShowCommentsList
,
selectShowCommentsGloballyOffError
}
from
'
../../redux/studio-permissions
'
;
import
{
selectStudioCommentsAllowed
}
from
'
../../redux/studio.js
'
;
import
StudioComment
from
'
./studio-comment.js
'
;
const
StudioComments
=
({
comments
,
...
...
@@ -37,12 +35,8 @@ const StudioComments = ({
shouldShowCommentComposer
,
shouldShowCommentsList
,
shouldShowCommentsGloballyOffError
,
username
,
canDeleteAnyComment
,
canDeleteOwnComment
,
canDeleteCommentWithoutConfirm
,
canEditCommentsAllowed
,
canReportComment
,
canRestoreComment
,
handleDeleteComment
,
handleRestoreComment
,
...
...
@@ -127,12 +121,9 @@ const StudioComments = ({
<
TopLevelComment
hasThreadLimit
author=
{
comment
.
author
}
canDelete=
{
canDeleteAnyComment
||
(
canDeleteOwnComment
&&
comment
.
author
.
username
===
username
)
}
canDeleteWithoutConfirm=
{
canDeleteCommentWithoutConfirm
}
canReply=
{
shouldShowCommentComposer
&&
commentsAllowed
}
canReport=
{
canReportComment
}
canRestore=
{
canRestoreComment
}
commentComponent=
{
StudioComment
}
content=
{
comment
.
content
}
datetimeCreated=
{
comment
.
datetime_created
}
defaultExpanded=
{
singleCommentId
}
...
...
@@ -190,12 +181,8 @@ StudioComments.propTypes = {
shouldShowCommentComposer
:
PropTypes
.
bool
,
shouldShowCommentsGloballyOffError
:
PropTypes
.
bool
,
shouldShowCommentsList
:
PropTypes
.
bool
,
username
:
PropTypes
.
string
,
canDeleteAnyComment
:
PropTypes
.
bool
,
canDeleteOwnComment
:
PropTypes
.
bool
,
canDeleteCommentWithoutConfirm
:
PropTypes
.
bool
,
canEditCommentsAllowed
:
PropTypes
.
bool
,
canReportComment
:
PropTypes
.
bool
,
canRestoreComment
:
PropTypes
.
bool
,
handleDeleteComment
:
PropTypes
.
func
,
handleRestoreComment
:
PropTypes
.
func
,
...
...
@@ -217,16 +204,12 @@ export default connect(
isAdmin
:
selectIsAdmin
(
state
),
moreCommentsToLoad
:
state
.
comments
.
moreCommentsToLoad
,
replies
:
state
.
comments
.
replies
,
username
:
selectUsername
(
state
),
commentsAllowed
:
selectStudioCommentsAllowed
(
state
),
shouldShowCommentComposer
:
selectShowCommentComposer
(
state
),
shouldShowCommentsGloballyOffError
:
selectShowCommentsGloballyOffError
(
state
),
shouldShowCommentsList
:
selectShowCommentsList
(
state
),
canDeleteAnyComment
:
selectCanDeleteAnyComment
(
state
),
canDeleteOwnComment
:
selectCanDeleteOwnComment
(
state
),
canDeleteCommentWithoutConfirm
:
selectCanDeleteCommentWithoutConfirm
(
state
),
canEditCommentsAllowed
:
selectCanEditCommentsAllowed
(
state
),
canReportComment
:
selectCanReportComment
(
state
),
canRestoreComment
:
selectCanRestoreComment
(
state
),
postURI
:
`/proxy/comments/studio/
${
state
.
studio
.
id
}
`
}),
...
...
test/unit/components/studio-comments.test.jsx
View file @
e331c20d
import
React
from
'
react
'
;
import
{
mountWithIntl
}
from
'
../../helpers/intl-helpers.jsx
'
;
import
{
StudioComments
}
from
'
../../../src/views/studio/studio-comments.jsx
'
;
// Replace customized studio comment with default comment to avoid redux issues in the test
jest
.
mock
(
'
../../../src/views/studio/studio-comment.js
'
,
()
=>
(
jest
.
requireActual
(
'
../../../src/views/preview/comment/comment.jsx
'
)
));
describe
(
'
Studio comments
'
,
()
=>
{
test
(
'
if there are no comments, they get loaded
'
,
()
=>
{
const
loadComments
=
jest
.
fn
();
...
...
test/unit/redux/studio-permissions.test.js
View file @
e331c20d
...
...
@@ -2,8 +2,7 @@ import {
selectCanEditInfo
,
selectCanAddProjects
,
selectShowCommentComposer
,
selectCanDeleteAnyComment
,
selectCanDeleteOwnComment
,
selectCanDeleteComment
,
selectCanDeleteCommentWithoutConfirm
,
selectCanReportComment
,
selectCanRestoreComment
,
...
...
@@ -189,17 +188,22 @@ describe('studio comments', () => {
describe
(
'
can report comment
'
,
()
=>
{
test
.
each
([
[
'
logged in
'
,
true
],
[
'
unconfirmed
'
,
fals
e
],
[
'
unconfirmed
'
,
tru
e
],
[
'
logged out
'
,
false
],
[
'
muted creator
'
,
true
],
[
'
muted logged in
'
,
true
]
])(
'
%s: %s
'
,
(
role
,
expected
)
=>
{
setStateByRole
(
role
);
expect
(
selectCanReportComment
(
state
)).
toBe
(
expected
);
expect
(
selectCanReportComment
(
state
,
'
not me
'
)).
toBe
(
expected
);
});
test
(
'
cannot report your own comment
'
,
()
=>
{
setStateByRole
(
'
logged in
'
);
const
loggedInUsername
=
selectUsername
(
state
);
expect
(
selectCanReportComment
(
state
,
loggedInUsername
)).
toBe
(
false
);
});
});
describe
(
'
can delete
any comment
'
,
()
=>
{
describe
(
'
can delete
others comments
'
,
()
=>
{
test
.
each
([
[
'
admin
'
,
true
],
[
'
curator
'
,
false
],
...
...
@@ -212,13 +216,13 @@ describe('studio comments', () => {
[
'
muted logged in
'
,
false
]
])(
'
%s: %s
'
,
(
role
,
expected
)
=>
{
setStateByRole
(
role
);
expect
(
selectCanDelete
AnyComment
(
state
)).
toBe
(
expected
);
expect
(
selectCanDelete
Comment
(
state
,
'
not me
'
)).
toBe
(
expected
);
});
});
describe
(
'
can delete own comment
'
,
()
=>
{
describe
(
'
can delete
my
own comment
'
,
()
=>
{
test
.
each
([
[
'
admin
'
,
false
],
// This is false here because we check for `canDeleteAnyComment` separately
[
'
admin
'
,
true
],
[
'
curator
'
,
false
],
[
'
manager
'
,
true
],
[
'
creator
'
,
true
],
...
...
@@ -231,7 +235,8 @@ describe('studio comments', () => {
[
'
muted logged in
'
,
false
]
])(
'
%s: %s
'
,
(
role
,
expected
)
=>
{
setStateByRole
(
role
);
expect
(
selectCanDeleteOwnComment
(
state
)).
toBe
(
expected
);
const
loggedInUsername
=
selectUsername
(
state
);
expect
(
selectCanDeleteComment
(
state
,
loggedInUsername
)).
toBe
(
expected
);
});
});
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment