Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wiki-js
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
1
Issues
1
List
Board
Labels
Milestones
Merge Requests
1
Merge Requests
1
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Jacklull
wiki-js
Commits
7c0d6e28
Commit
7c0d6e28
authored
Sep 09, 2020
by
NGPixel
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
fix: prevent write:groups from self-promoting
parent
f988c5f8
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
110 additions
and
12 deletions
+110
-12
auth.js
server/core/auth.js
+28
-0
group.js
server/graph/resolvers/group.js
+82
-12
No files found.
server/core/auth.js
View file @
7c0d6e28
...
...
@@ -287,6 +287,34 @@ module.exports = {
},
/**
* Check for exclusive permissions (contain any X permission(s) but not any Y permission(s))
*
* @param {User} user
* @param {Array<String>} includePermissions
* @param {Array<String>} excludePermissions
*/
checkExclusiveAccess
(
user
,
includePermissions
=
[],
excludePermissions
=
[])
{
const
userPermissions
=
user
.
permissions
?
user
.
permissions
:
user
.
getGlobalPermissions
()
// System Admin
if
(
userPermissions
.
includes
(
'manage:system'
))
{
return
true
}
// Check Inclusion Permissions
if
(
_
.
intersection
(
userPermissions
,
includePermissions
).
length
<
1
)
{
return
false
}
// Check Exclusion Permissions
if
(
_
.
intersection
(
userPermissions
,
excludePermissions
).
length
>
0
)
{
return
false
}
return
true
},
/**
* Check and apply Page Rule specificity
*
* @access private
...
...
server/graph/resolvers/group.js
View file @
7c0d6e28
const
graphHelper
=
require
(
'../../helpers/graph'
)
const
safeRegex
=
require
(
'safe-regex'
)
const
_
=
require
(
'lodash'
)
const
gql
=
require
(
'graphql'
)
/* global WIKI */
const
gql
=
require
(
'graphql'
)
module
.
exports
=
{
Query
:
{
async
groups
()
{
return
{}
}
async
groups
()
{
return
{}
}
},
Mutation
:
{
async
groups
()
{
return
{}
}
async
groups
()
{
return
{}
}
},
GroupQuery
:
{
async
list
(
obj
,
args
,
context
,
info
)
{
/**
* FETCH ALL GROUPS
*/
async
list
()
{
return
WIKI
.
models
.
groups
.
query
().
select
(
'groups.*'
,
WIKI
.
models
.
groups
.
relatedQuery
(
'users'
).
count
().
as
(
'userCount'
)
)
},
async
single
(
obj
,
args
,
context
,
info
)
{
/**
* FETCH A SINGLE GROUP
*/
async
single
(
obj
,
args
)
{
return
WIKI
.
models
.
groups
.
query
().
findById
(
args
.
id
)
}
},
GroupMutation
:
{
async
assignUser
(
obj
,
args
)
{
/**
* ASSIGN USER TO GROUP
*/
async
assignUser
(
obj
,
args
,
{
req
})
{
// Check for guest user
if
(
args
.
userId
===
2
)
{
throw
new
gql
.
GraphQLError
(
'Cannot assign the Guest user to a group.'
)
}
// Check for valid group
const
grp
=
await
WIKI
.
models
.
groups
.
query
().
findById
(
args
.
groupId
)
if
(
!
grp
)
{
throw
new
gql
.
GraphQLError
(
'Invalid Group ID'
)
}
// Check assigned permissions for write:groups
if
(
WIKI
.
auth
.
checkExclusiveAccess
(
req
.
user
,
[
'write:groups'
],
[
'manage:groups'
,
'manage:system'
])
&&
grp
.
permissions
.
some
(
p
=>
{
const
resType
=
_
.
last
(
p
.
split
(
':'
))
return
[
'users'
,
'groups'
,
'navigation'
,
'theme'
,
'api'
,
'system'
].
includes
(
resType
)
})
)
{
throw
new
gql
.
GraphQLError
(
'You are not authorized to assign a user to this elevated group.'
)
}
// Check for valid user
const
usr
=
await
WIKI
.
models
.
users
.
query
().
findById
(
args
.
userId
)
if
(
!
usr
)
{
throw
new
gql
.
GraphQLError
(
'Invalid User ID'
)
}
// Check for existing relation
const
relExist
=
await
WIKI
.
models
.
knex
(
'userGroups'
).
where
({
userId
:
args
.
userId
,
groupId
:
args
.
groupId
...
...
@@ -41,8 +70,11 @@ module.exports = {
if
(
relExist
)
{
throw
new
gql
.
GraphQLError
(
'User is already assigned to group.'
)
}
// Assign user to group
await
grp
.
$relatedQuery
(
'users'
).
relate
(
usr
.
id
)
// Revoke tokens for this user
WIKI
.
auth
.
revokeUserTokens
({
id
:
usr
.
id
,
kind
:
'u'
})
WIKI
.
events
.
outbound
.
emit
(
'addAuthRevoke'
,
{
id
:
usr
.
id
,
kind
:
'u'
})
...
...
@@ -50,7 +82,10 @@ module.exports = {
responseResult
:
graphHelper
.
generateSuccess
(
'User has been assigned to group.'
)
}
},
async
create
(
obj
,
args
)
{
/**
* CREATE NEW GROUP
*/
async
create
(
obj
,
args
,
{
req
})
{
const
group
=
await
WIKI
.
models
.
groups
.
query
().
insertAndFetch
({
name
:
args
.
name
,
permissions
:
JSON
.
stringify
(
WIKI
.
data
.
groups
.
defaultPermissions
),
...
...
@@ -64,7 +99,14 @@ module.exports = {
group
}
},
async
delete
(
obj
,
args
)
{
/**
* DELETE GROUP
*/
async
delete
(
obj
,
args
)
{
if
(
args
.
id
===
1
||
args
.
id
===
2
)
{
throw
new
gql
.
GraphQLError
(
'Cannot delete this group.'
)
}
await
WIKI
.
models
.
groups
.
query
().
deleteById
(
args
.
id
)
WIKI
.
auth
.
revokeUserTokens
({
id
:
args
.
id
,
kind
:
'g'
})
...
...
@@ -77,7 +119,16 @@ module.exports = {
responseResult
:
graphHelper
.
generateSuccess
(
'Group has been deleted.'
)
}
},
async
unassignUser
(
obj
,
args
)
{
/**
* UNASSIGN USER FROM GROUP
*/
async
unassignUser
(
obj
,
args
)
{
if
(
args
.
userId
===
2
)
{
throw
new
gql
.
GraphQLError
(
'Cannot unassign Guest user'
)
}
if
(
args
.
userId
===
1
&&
args
.
groupId
===
1
)
{
throw
new
gql
.
GraphQLError
(
'Cannot unassign Administrator user from Administrators group.'
)
}
const
grp
=
await
WIKI
.
models
.
groups
.
query
().
findById
(
args
.
groupId
)
if
(
!
grp
)
{
throw
new
gql
.
GraphQLError
(
'Invalid Group ID'
)
...
...
@@ -95,17 +146,34 @@ module.exports = {
responseResult
:
graphHelper
.
generateSuccess
(
'User has been unassigned from group.'
)
}
},
async
update
(
obj
,
args
)
{
/**
* UPDATE GROUP
*/
async
update
(
obj
,
args
,
{
req
})
{
// Check for unsafe regex page rules
if
(
_
.
some
(
args
.
pageRules
,
pr
=>
{
return
pr
.
match
===
'REGEX'
&&
!
safeRegex
(
pr
.
path
)
}))
{
throw
new
gql
.
GraphQLError
(
'Some Page Rules contains unsafe or exponential time regex.'
)
}
// Set default redirect on login value
if
(
_
.
isEmpty
(
args
.
redirectOnLogin
))
{
args
.
redirectOnLogin
=
'/'
}
// Check assigned permissions for write:groups
if
(
WIKI
.
auth
.
checkExclusiveAccess
(
req
.
user
,
[
'write:groups'
],
[
'manage:groups'
,
'manage:system'
])
&&
args
.
permissions
.
some
(
p
=>
{
const
resType
=
_
.
last
(
p
.
split
(
':'
))
return
[
'users'
,
'groups'
,
'navigation'
,
'theme'
,
'api'
,
'system'
].
includes
(
resType
)
})
)
{
throw
new
gql
.
GraphQLError
(
'You are not authorized to manage this group or assign these permissions.'
)
}
// Update group
await
WIKI
.
models
.
groups
.
query
().
patch
({
name
:
args
.
name
,
redirectOnLogin
:
args
.
redirectOnLogin
,
...
...
@@ -113,9 +181,11 @@ module.exports = {
pageRules
:
JSON
.
stringify
(
args
.
pageRules
)
}).
where
(
'id'
,
args
.
id
)
// Revoke tokens for this group
WIKI
.
auth
.
revokeUserTokens
({
id
:
args
.
id
,
kind
:
'g'
})
WIKI
.
events
.
outbound
.
emit
(
'addAuthRevoke'
,
{
id
:
args
.
id
,
kind
:
'g'
})
// Reload group permissions
await
WIKI
.
auth
.
reloadGroups
()
WIKI
.
events
.
outbound
.
emit
(
'reloadGroups'
)
...
...
@@ -125,7 +195,7 @@ module.exports = {
}
},
Group
:
{
users
(
grp
)
{
users
(
grp
)
{
return
grp
.
$relatedQuery
(
'users'
)
}
}
...
...
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